⍝ Evaluator for a subset of Scheme: s ← '((lambda (cons car cdr)' s,← ' (car (cons 123 456)))' s,← '' s,← ' (lambda (x y) (lambda (i) (cond (i x) (else y))))' s,← ' (lambda (xy) (xy 0))' s,← ' (lambda (xy) (xy 1)))' lisp s 456 lisp '''(* 4 5)' ┌─┬─┬─┐ │*│4│5│ └─┴─┴─┘ ⍝ f→(x→x x)(x→f(y→(x x)y)) Y ← '(\(f)((\(x)(x x))(\(x)(f(\(y)((x x)y))))))' ⍝ fixpoint Y' fac ← '(\(f)(\(n)(cond((= n 0)1)(else(* n(f(- n 1)))))))' ⍝ factorial lisp '((',Y,fac,')4)' 24 ⍝ Ackermann: ack ← '(\(a)(\(m)(\(n)(cond((= m 0)(+ n 1))' ack ,← ' ((= n 0)((a(- m 1))1))' ack ,← ' (else((a(- m 1))((a m)(- n 1))))))))' lisp'(((',Y,ack,')2)2)' 7 ⍝ Fibonacci: fib ← '(\(f)(\(n)(cond((= n 0)0)((= n 1)1)(else(+(f(- n 1))(f(- n 2)))))))' rec←{'((',Y,⍺,')',⍵,')'} ⍝ Y applicator lisp¨ fib∘rec¨ ⎕d ⍝ fib¨ 0..9 0 1 1 2 3 5 8 13 21 34 pdep ← {+\1 ¯1 0['()'⍳⍵]} ⍝ paren depth pchk←{0 ¯1↓1 0⌽' ',⍕↑pdep\⍵ ⍵} ⍝ handy paren depth checker pchk Y ( \ ( f ) ( ( \ ( x ) ( x x ) ) ( \ ( x ) ( f ( \ ( y ) ( ( x x ) y ) ) ) ) ) ) 1 1 2 2 1 2 3 3 4 4 3 4 4 4 4 3 2 3 3 4 4 3 4 4 5 5 6 6 5 6 7 7 7 7 6 6 5 4 3 2 1 pic2←{ ⍝ 2D paren depth picture d←(⍵=')')+pdep ⍵ ⍝ depth ⊖d⊖⍵⍪((¯1+⌈/d),⍴⍵)⍴'·' ⍝ pic } pic2 Y ⍝ applicative order Y combinator (\·······································) ··(f)(··································)· ······(\········)(\····················)·· ········(x)(x x)···(x)(f··············)··· ························(\···········)···· ··························(y)(·····y)····· ······························(x x)······· ⍝ h→(x→h(x x))(x→h(x x)) pic2 '(\(h)((\(x)(h(x x)))(\(x)(h(x x)))))' ⍝ normal order Y combinator (\·································) ··(h)(····························)· ······(\···········)(\···········)·· ········(x)(h·····)···(x)(h·····)··· ·············(x x)·········(x x)···· pic2 '(h→(x→h(x x))(x→h(x x)))' ⍝ same again using → notation (h→····················) ···(x→h·····)(x→h·····)· ·······(x x)·····(x x)·· ⍝ h→(y→y y)(x→h(x x)) pic2 '(\(h)((\(y)(y y))(\(x)(h(x x)))))' ⍝ recoding of the above (\······························) ··(h)(·························)· ······(\········)(\···········)·· ········(y)(y y)···(x)(h·····)··· ························(x x)···· pic2 '(h→(y→y y)(x→h(x x)))' ⍝ same again using → notation (h→·················) ···(y→y y)(x→h·····)· ··············(x x)·· svec ← (' (' '(')('lambda' '\') ⍝ substitution vector. trim ← {(~' '⍷⍵)/⍵} ⍝ without superfluous blanks. pic2 ↑subs/ svec,⊂trim s ⍝ Nick's example: (·······························································································) ·(\·································)(\······························)(\··········)(\··········)· ···(cons car cdr)(car··············)···(x y)(\······················)···(xy)(xy 0)···(xy)(xy 1)·· ·····················(cons 123 456)···········(i)(cond·············)····························· ······················································(i x)(else y)······························ ⍝∇ lisp subs Back to: code Back to: Workspaces