Posted by azhenley 6 hours ago
It was a "nerd" exploration few decades ago but nowadays so many of the things we do, from buying croissant to voting, is based on hardware and software. People should have a sense that yes it's complex but it's also NOT magic.
How large would implementation be in more usual languages?
Int L[A],m,b,*D=A,
*c,*a=L,C,*U=L,u;s
(_){u--&&s(a=*a);}
char*B,I,O;S(){b=b
--?b:m|read(0,&I,1
)-1;return~I>>b&1;
}k(l,u){for(;l<=u;
U-L<A?*U++=46^l++[
"-,&,,/.--/,:-,'/"
".-,-,,/.-,*,//..,"
]:exit(5));}p(Int*m){
return!*U?*m=S()?U++,!S
()?m[1]=p(++U),2:3:1,p(U)
:S()?U+=2:p(U[1]++),U-m;}x(
c){k(7*!b,9);*U++=b&&S();c&&x
(b);}d(Int*l){--l[1]||d(l[d(*l),
*l=B,B=l,2]);}main(e){for(k(10,33
),a[4]-=m=e-2&7,a[23]=p(U),b=0;;e-2
?e?e-3?s(D=a),C=a [3],++1[a=a[2]],d(
D):c?D=c,c=*D,*D= a,a=D:exit(L[C+1])
:C--<23?C=u+m&1?O =O+O|C&1,9:write(m
||(O=C+28),&O,1)+ 1:(S(),x(0<b++?k(0,
6),U[-5]=96:0)):( D=B?B:calloc(4,X))
?B=*D,*D=c,c=D,D[ 2]=a,a[++D[1]]++,D
[3]=++C+u:exit(6) )e=L[C++],u=L[C];}
while a less obfuscated and highly performant implementation https://github.com/tromp/AIT/blob/master/uni.c based on combinatory graph reduction takes 446 lines.But the Lisp way it's far more elegant.
function (v) { return e ; } -> Uncaught SyntaxError: Function statements require a function name
function a (v) { return e ; } a() -> Uncaught ReferenceError: e is not defined
Am I missing something?
f = function (v) { return e ; }
or (function (v) { return e ; })
Javascript doesn't allow (nameless) function expressions (using the function keyword) where a function statement would work.(and that particular function can also be written v => e)
As for the e being undefined when you execute the function, you should see it as a free variable [1], supposed to be defined elsewhere or replaced with something else.
[1] https://en.wikipedia.org/wiki/Free_variables_and_bound_varia...
He is just showing how the syntax of a Scheme function corresponds to the structure of a JavaScript function.
I have been playing with an s-expr based language that compiles to f sharp, and it has made me realize how much I think Rich Hickey made some very lovely choices for clojure. I have never written clojure more than just for fun, but the more in think about my own toy language, the more highly I think of Rich Hickey. Many times because of the choices he made, but even more because of how he compromised to be able to interop with java.
His first publication that showed the elements of the lambda calculus was the 1932 paper "A set of postulates for the foundation of logic", as I cited in my recent paper [1]. It's quite possible he worked on it prior to 1932, but I don't know of any credible evidence on that (would be very interested to learn about any).
> Wait! How the heck is this a "programming" language? > At first glance, this simple language seems to lack both recursion and iteration, not to mention numbers, booleans, conditionals, data structures and all the rest. How can this language possibly be general-purpose?
What most stops lambda calculus from being a programming language is that it doesn't directly support I/O. However, one can adopt some very simple conventions for representing bits, lists of bits (bytes), and lists of bytes, and for letting a lambda term operate on these [2] which make the so-called Binary Lambda Calculus (BLC) a programming language.
And a very expressive language it is too: a BLC self interpreter [4] can be as small as the 170-bits
01000110100001000
00001100000010111
00110000111111100
00101110011111110
00000111100000010
11101110011011110
01111111100001111
11110000101111010
01110100101111101
00101101010011010
which encodes the term
(λ11)(λ(λλλ1(λλ2(1(λ6(λ2(6(λλ3(λλ23(14))))(7(λ7(λ31(21)))))))(41(111))))(11))
in De Bruijn notatation, with lambda diagram [3] ┬─┬ ────────────────────────────────────────────┬─┬
└─┤ ──────┬───────────────┬──────────────────── ├─┘
│ ──────┼───┬───────────┼─┬─────────┬──────── │
│ ┬─────┼───┼───────────┼─┼─────────┼──────── │
│ │ ┬───┼───┼───────────┼─┼─────────┼──────── │
│ │ ┼─┬─┼───┼───────────┼─┼─────────┼─┬─┬─┬─┬ │
│ │ │ │ ┼─┬─┼───────────┼─┼──────── └─┤ └─┤ │ │
│ │ │ │ │ ┼─┼─┬─────────┼─┼─┬────── │ ├─┘ │
│ │ │ │ │ │ │ ┼───────┬ │ ┼─┼───┬── ├───┘ │
│ │ │ │ │ │ │ ┼───┬───┼ │ │ ┼─┬─┼─┬ │ │
│ │ │ │ │ │ │ │ ┬─┼───┼ │ │ └─┤ ├─┘ │ │
│ │ │ │ │ │ │ │ ┼─┼─┬─┼ │ │ ├─┘ │ │
│ │ │ │ │ │ │ │ └─┤ ├─┘ │ ├───┘ │ │
│ │ │ │ │ │ │ │ ├─┘ ├─┘ │ │
│ │ │ │ │ │ │ ├───┘ │ │ │
│ │ │ │ │ │ ├─┘ │ │ │
│ │ │ │ │ └─┤ │ │ │
│ │ │ │ │ ├───────────┘ │ │
│ │ │ │ ├───┘ │ │
│ │ │ ├─┘ │ │
│ │ └─┤ │ │
│ │ ├───────────────────────────────┘ │
│ └───┤ │
│ ├───────────────────────────────────────┘
└─────┘
10 times smaller than the 7 lines of R5RS Scheme (define (eval e env) (cond
((symbol? e) (cadr (assq e env)))
((eq? (car e) 'λ) (cons e env))
(else (apply (eval (car e) env) (eval (cadr e) env)))))
(define (apply f x)
(eval (cddr (car f)) (cons (list (cadr (car f)) x) (cdr f))))
(display (eval (read) '())) (newline)
> This code will read a program from stdin, parse it, evaluate it and print the result.Except that it leaves all the actual parsing to the "read" library function.
In contrast, the BLC code does all parsing itself. One of the neatest tricks is how it represents the environment as a list built with
cons' = \x\y\zx\zy. zx x (zy y)
which allows a list of bits like "1110" (the code for de Bruijn index 3) to index the environment by simply applying it to the environment.[1] https://www.mdpi.com/1099-4300/28/5/494 "The Largest Number Representable in 64 Bits"
[2] https://gist.github.com/tromp/86b3184f852f65bfb814e3ab0987d8...