The Confluence of APL and Lisp: A 90-Line Python Revelation
#Python

The Confluence of APL and Lisp: A 90-Line Python Revelation

Tech Essays Reporter
2 min read

Mohammed Alrujayi's implementation of K—a fusion of APL's notation and Lisp's semantics—in 90 lines of Python demonstrates how scalar extension bridges two foundational programming paradigms, revealing their shared DNA while challenging modern array computing conventions.

The quest to merge the semantic elegance of Lisp with the syntactic density of array programming has captivated computer scientists since Alan Perlis posed the question in 1979. Mohammed Alrujayi's recent implementation of K—Arthur Whitney's synthesis of these paradigms—in merely 90 lines of Python offers a profound demonstration of their shared computational DNA. This minimalist implementation transcends academic curiosity, revealing how scalar extension via higher-order functions can resurrect Iversonian array processing within Python's native lists, bypassing heavyweight numerical libraries while illuminating a path toward expressive concision.

Golfing APL/K in 90 Lines of Python - by Mohammed Alrujayi

The historical divergence between these paradigms traces to their origins: McCarthy's Lisp emerged from lambda calculus and symbolic manipulation at MIT, while Iverson's APL—visually encoded in hieroglyphic-like glyphs—originated from mathematical notation at Harvard. Both shared a radical minimalism: Lisp's universal list structure mirrored APL's n-dimensional arrays. For decades, their communities evolved in parallel, with Perlis's panel concluding without resolution on unification. Whitney's insight—that Lisp's nested lists could subsume APL's arrays while preserving its vocabulary—culminated in K (1992), which discarded APL's multidimensional model for Lisp-like recursion while retaining its operators.

Golfing APL/K in 90 Lines of Python - by Mohammed Alrujayi

Alrujayi's implementation crystallizes this synthesis through two higher-order functions: monad and dyad. These recursively vectorize operations across Python lists, enabling APL-style pervasive computation without specialized arrays. Consider monad(math.sqrt) permeating nested lists: applied to [[4,9],[16,25]], it yields [[2.0,3.0],[4.0,5.0]]—no loops or NumPy required. Similarly, dyad handles scalar extension: add(10, [1,2,3]) becomes [11,12,13]. This machinery supports K's famed expressiveness—calculating primes via &2=+/0=(a)mod/a:1+!50 or the golden ratio through 0{1+1%x}/1—all executed through Python's existing list primitives.

Golfing APL/K in 90 Lines of Python - by Mohammed Alrujayi

The implications extend beyond code golfing. By demonstrating Iverson's broadcasting and reduction semantics (+/ for sum, ! for range) in 90 lines, Alrujayi exposes how modern array libraries like NumPy and PyTorch are elaborate reimplementations of APL's 1960s operators. Yet counterperspectives arise: while elegant, this approach sacrifices the memory efficiency and hardware acceleration of contiguous arrays. Recursive tree traversal cannot match NumPy's vectorized SIMD operations, nor does it support APL's rank polymorphism. The terse syntax—while powerful—conflicts with Python's readability ethos, potentially limiting adoption.

Ultimately, this miniature K interpreter embodies Perlis's unrealized vision: Lisp's structural flexibility merged with APL's notational density. It challenges the assumption that array programming necessitates complex dependencies, proving that scalar extension alone can resurrect Iverson's ghosts within vanilla Python. As Whitney observed, the fusion creates "a stripped-down version of APL" with "about 50 operations"—a testament to how computational elegance emerges not from expansion, but distillation. The Epython implementation remains available on GitHub for further exploration.

Comments

Loading comments...