
Show HN: A Lisp interpreter in C# 7 - suzuki
https://github.com/nukata/lisp-in-cs
======
garganzol
Despite its humble size, this is a pretty sophisticated Lisp implementation.
Not that one that can only do some additions, but also macros and stuff.

Kudos for doing the Lisp thing right.

UPDATE: Took one more look, this implementation is really impressive. It does
stuff like 'defmacro', the whole code is just 1400 lines of C#. Never saw
anything that effective in terms of functionality per line of code till this
day. Impressive, very impressive. Also thanks for sharing.

~~~
suzuki
Thank you. This Lisp is a translation of my other Lisp in 1200 lines of Dart
([https://github.com/nukata/lisp-in-dart](https://github.com/nukata/lisp-in-
dart)), which is, in turn, a digest or refinement of my old L2Lisp in Java
([https://github.com/nukata/l2lisp-in-java](https://github.com/nukata/l2lisp-
in-java)). I did my best to optimize it for C# 7.

~~~
garganzol
Good job Mr. Suzuki. You effort on C# 7 optimization shows, the result is
clean and professional.

Regarding the speed of .NET implementation, it can be improved by leveraging
LINQ expressions trees. In this way, one can achieve a good interpreter/JIT
combo. The compiled code produced by LINQ expression trees is discardable. So
you can temporarily cache it for frequent Lisp expressions (this gives JIT
performance), and then discard rarely used parts of it (this gives a
flexibility of an interpreter).

I'm myself in a Scheme camp of Lisp, but I love your implementation. This is
the cleanest one I saw in years.

------
earenndil
Neat! One thing to mention, I would remove most of the benchmarks, and include
only clisp, sbcl (I guarantee you this one is the fastest), clozure cl (ccl),
and abcl.

~~~
suzuki
I wonder if it might be unfair to include the byte-compiled results (with
_.fast and_.elc files) of CLISP and Emacs Lisp to the table.

------
hestefisk
Neat work! Also good demonstration of new C# 7.0 features.

~~~
suzuki
Thank you. I appreciated especially the pattern matching feature of C# 7 while
programming the interpreter. For example:

    
    
            /// <summary>Evaluate a Lisp expression in an environment.</summary>
            public object Eval(object x, Cell env) {
                try {
                    for (;;) {
                        switch (x) {
                        case Arg xarg:
                            return xarg.GetValue(env);
                        case Sym xsym:
                            try {
                                return Globals[xsym];
                            } catch (KeyNotFoundException) {
                                throw new EvalException("void variable", x);
                            }
                        case Cell xcell:

