cmgn.io/posts/lisp

August 2023

Python 3.11.4 (main, Jun 20 2023, 17:23:00) [Clang 14.0.3 (clang-1403.0.22.14.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> (d:=(lambda s:s.replace('(',' ( ').replace(')',' ) ').split()),p:=(lambda toks:(v:=(lambda toks,x:(toks,x)if not toks else(toks[1:],x)if toks[0]==')' else(t:=p(toks[1:]),v(t[0],x+[t[1]]))[-1]if toks[0]=='(' else v(toks[1:],x+[int(toks[0])])if toks[0].isdigit()else v(toks[1:],x+[toks[0]])),v(toks,[]))[-1]),h:=(lambda e,c:e if isinstance(e,(int,type(None)))else c[e]if isinstance(e,str)else h(e[0],c)(e[1:],c)),c:={'+':lambda k,c:sum([h(z,c)for z in k]),'-':lambda k,c:__import__('functools').reduce(int.__sub__,[h(z,c)for z in k]),'*':lambda k,c:__import__('functools').reduce(int.__mul__,[h(z,c)for z in k]),'/':lambda k,c: __import__('functools').reduce(int.__floordiv__,[h(z,c)for z in k]),'quote':lambda k,c:k[0],'cond':lambda k,c:(rec:=lambda k:None if not k else h(k[0][1],c)if h(k[0][0],c)else rec(k[1:]),rec(k),)[-1],'lambda':lambda k,c:(ps:=k[0],bb:=k[1],lambda c_a,c_c:h(bb,__import__('collections').ChainMap(dict(zip(ps,(h(z,c_c)for z in c_a))),c),),)[-1],'car':lambda k,c:h(k[0],c)[0],'cdr':lambda k,c:h(k[0],c)[1:],'cons':lambda k,c:[h(k[0],c)] +h(k[1],c),'define':lambda k,c:c.__setitem__(k[0],h(k[1],c)),'eq':lambda k,c:int(h(k[0],c)==h(k[1],c))}, repl:=(lambda:(print('lisp> ',end=''),s:=input(),None if s=='quit' else(t:=p(d(s)),print(h(t[1][0],c)),repl()))))[-1]()

lisp> (define fact (lambda (n) (cond ((eq n 0) 1) ((eq 1 1) (* n (fact (- n 1)))))))
None
lisp> (fact 5)
120
lisp> (define fib (lambda (n) (cond ((eq n 1) 1) ((eq n 2) 1) ((eq 1 1) (+ (fib (- n 1)) (fib (- n 2)))))))
None
lisp> (fib 5)
5
lisp> (fib 10)
55
      

Or, formatted more nicely:

(
    d := (lambda s: s.replace("(", " ( ").replace(")", " ) ").split()),
    p := (
        lambda toks: (
            v := (
                lambda toks, x: (toks, x)
                if not toks
                else (toks[1:], x)
                if toks[0] == ")"
                else (t := p(toks[1:]), v(t[0], x + [t[1]]))[-1]
                if toks[0] == "("
                else v(toks[1:], x + [int(toks[0])])
                if toks[0].isdigit()
                else v(toks[1:], x + [toks[0]])
            ),
            v(toks, []),
        )[-1]
    ),
    h := (
        lambda e, c: e
        if isinstance(e, (int, type(None)))
        else c[e]
        if isinstance(e, str)
        else h(e[0], c)(e[1:], c)
    ),
    c := {
        "+": lambda k, c: sum([h(z, c) for z in k]),
        "-": lambda k, c: __import__("functools").reduce(
            int.__sub__, [h(z, c) for z in k]
        ),
        "*": lambda k, c: __import__("functools").reduce(
            int.__mul__, [h(z, c) for z in k]
        ),
        "/": lambda k, c: __import__("functools").reduce(
            int.__floordiv__, [h(z, c) for z in k]
        ),
        "quote": lambda k, c: k[0],
        "cond": lambda k, c: (
            rec := lambda k: None
            if not k
            else h(k[0][1], c)
            if h(k[0][0], c)
            else rec(k[1:]),
            rec(k),
        )[-1],
        "lambda": lambda k, c: (
            ps := k[0],
            bb := k[1],
            lambda c_a, c_c: h(
                bb,
                __import__("collections").ChainMap(
                    dict(zip(ps, (h(z, c_c) for z in c_a))), c
                ),
            ),
        )[-1],
        "car": lambda k, c: h(k[0], c)[0],
        "cdr": lambda k, c: h(k[0], c)[1:],
        "cons": lambda k, c: [h(k[0], c)] + h(k[1], c),
        "define": lambda k, c: c.__setitem__(k[0], h(k[1], c)),
        "eq": lambda k, c: int(h(k[0], c) == h(k[1], c)),
    },
    repl := (
        lambda: (
            print("lisp> ", end=""),
            s := input(),
            None if s == "quit" else (t := p(d(s)), print(h(t[1][0], c)), repl()),
        )
    ),
)[-1]()