Saturday, August 20, 2011

Praising Kernel

I love Kernel! Let's face it: While Paul Graham has reanimated Lisp, Lisp has become stuck in a rut. CL hasn't changed since '94, and it probably won't, and heck, that's even a good thing - CL is the mud ball of strength, the acting patriarch of the Lisp family. There's a better chance of CL being around in 50 years than most other programming languages. The same for Scheme, although it's in a bit of an identity crisis right now. But what's crazy about Scheme is that it has become focused on ahead-of-time compilation, in a world where people run Linux in JavaScript JIT compilers. One of the purposes of Scheme should be to push compiler writers to be smarter. Let's forget all that static, performance-oriented stuff, let's make it as dynamic and general and simple as it can get, and spend the following decades on amazing new tech to make it fast! That's what Scheme's about, right? And let's not talk about Clojure, they don't even "see the need" for EVAL [in ClojureScript]. So much for the state of Lisp. Can you see it? We need to put the fun, nasty fun, back into Lisp. Lisp has been resting on its well-deserved laurels for much too long. Heck, even Java is getting lambdas now, and there's talk of macros in JavaScript. Lisp's purpose in the programming language galaxy is to assist our most gifted fellow humans in thinking previously impossible thoughts, remember? Do you really think current Lisps are up to that task?

So where does Kernel fit in? In short, I think Kernel is as close as you can get to the essence, the rhyming scheme of Lisp. Whereas the R6RS doesn't even mention interactive development, Kernel is squarely interactive. And it provides crystal clear semantics to go with it. LETREC blackhole? Hopeless toplevel? Not in Kernel. First-class environments solve these issues. Look, Kernel has a single form, $vau, that is as powerful as lambda, define-syntax, and let-syntax combined! (Strike that, it's even more powerful - you can use Kernel's macros, fexprs, just like ordinary functions.) Need I say more? Kernel can truly bootstrap itself from its 3 (or less) built-in forms (counting them is not easy), without the need for a separate expansion process, and without the need for a hygiene system - Kernel is simply inherently hygienic (when used right). Another form, $define!, not only takes on the roles of define and set!, but also doubles, nay, triples, nay, n-tuples, as a primitive for arbitrary namespace manipulation - you can build any module system you like on top of this single primitive! Think about it? Can your language do that? Fat chance! But should your Lisp be able to do that? I'd say. Now, you say, but no one has written real applications in Kernel yet. I say: that's what's so cool about it! It's a brave new world, without trodden paths, full of new discoveries in semantics, implementation technologies, and other things we can't even see yet. In the past 50 years, Lisp has succeeded in bringing object-orientation, dynamism, functional programming, and other niceties to the philistines. Soon, they'll even have macros and EVAL. Now it's time for Lisp to move another 50 years forward. That's what Lisp is for! And as far as I can see, Kernel is the vehicle for that. So fire up your printers, print out John Shutt's amazing works Fexprs as the basis of Lisp function application; or, $vau: the ultimate abstraction and the Revised -1 Report on the Kernel Programming Language, bind them, study them, and start hacking on Lisp's future! It's easy (nah, OK, it's hard) and it starts with you!

6 comments:

Oskar said...

Can you give an example of where eval is useful? I'm genuinely curious. I have been trying out Clojure, and most cases I have encountered where something like eval was needed had to do with looking up the value of a symbol, but that can be done with 'resolve'.

Manuel Simoni said...

EVAL is really at the heart of where Lisp shines most: complex, serious applications that can be extended while they are running. Emacs, 3D editors, movie editing tools, they all come with command languages, and by writing the application (or parts thereof) in Lisp, and/or offering APIs to Lisp, huge power is gained. See Stallman's Emacs paper.

It's true that ordinarily, you don't need EVAL, but for complex applications, it's a must. As Alan Perlis said: "A good system can't have a weak command language." EVAL is the way to make your application truly self-extensible and powerful.

dmbarbour said...

Built-in eval is dubious as a language feature, especially if you have first-class functions. But having it as a readily accessible library is nice.

Jay K. said...

Is there an implementation of Kernel somewhere? The author's site has a half baked one.

Manuel Simoni said...

I just discovered this implementation: https://bitbucket.org/AndresNavarro/klisp

Bendlas said...

Great article. I'll definitely have a look at kernel now.

Just a small correction: Eval most definitely is in clojure. It's been left out of clojurescript (the impl compiling to js). This is reasonable for a language, that uses static analysis to eliminate dead code.