John Fremlin's blog: Three unique features of Lisp in 2010

Posted 2010-05-14 22:00:00 GMT

Lisp's (and especially Scheme's) greatness is its coherence — instead of expressions, statements, sequence points and so on, it just has expressions. In implementations, instead of separate tools for compiler, debugger, profiler, you generally have one tool and, if you have the source, can in a unified way examine and fluidly adapt any part. This is never going to fly in the Balkanized world of other languages, where the compiler is generally not implemented in the language itself.

Mainstream languages like JavaScript, Python, C#, C++ and Java have steadily adopted some of Lisp's ideas (e.g. garbage collection (1959)), but some, sadly, remain overlooked. Having moved back to programming in C++ and doing some C#, I'm constantly amazed that some really fundamental things from Lisp remain shrouded in mysterious brackets.

1. In my opinion, most basic and most overlooked are the benefits of usable global variables. In Lisp you don't have to keep passing extra parameters to functions because a function they call needs them. Each special variable has its own stack (per-thread in most implementations, leading to performance compromises). So you can use global variables without worrying about affecting other contexts.

Historically, lexical scoping is relatively new to Lisp (last thirty years?), and as it is much cleaner as a default, old Lisp's dynamic or special scoping received a bad name. But in the right places it makes the difference between having to add a parameter to a chain of function calls or adding an unnecessary field to a class, and simply implementing the needed functionality.

2. The condition system by Kent Pitman is utterly fantastic. C++'s STL is vastly better thought out than Common Lisp's sequences; but the conditions system in Common Lisp is a leap ahead of C++'s exceptions. Instead of an exception automatically unwinding the stack, callers can choose to catch a specific exception (called a condition) and perform some action — like, say, popping up a dialog box asking the user to free up disk space and retry — all without affecting the control flow. You're free to unwind the stack if you like of course. In implementation, this is normally pretty much a library on top of the language using special variables and closures. . .

3. Which brings me on to powerful closures. C++ is getting lambda functions, but they're not as powerful as Common Lisp's. Python resists allowing you to modify variables in the enclosing scope. In a Common Lisp lambda, you can not only modify variables in your enclosing lexical scope, but also return-from the enclosing scope (provided of course that it's still on the stack). This can be implemented by an exception with a tag unique to the enclosing function in C++ and other languages. But it is immensely useful, and much more convenient to have the compiler insert the boilerplate for you, as it allows all sorts of things.

It would be great if some these ideas would be massaged into other languages.

Is C++'s STL comparable to crhodes's user-extensible sequences?

(http://www.doc.gold.ac.uk/~mas01cr/papers/ilc2007/sequences-20070301.pdf)

Posted 2010-05-16 00:43:08 GMT by Anonymous from 173.62.227.175

The user-extensible sequences are cool. But the STL is much bigger than that http://www.stlport.org/resources/StepanovUSA.html

Posted 2010-05-26 21:35:00 GMT by John Fremlin

One of the reasons many languages are lacking cool features that already had a long history before these languages came into being might be the fact that most language writers have to rewrite all that stuff when they start a new language.

Btw, Java did not include closures and generics for the simple reason that they didn't have time for it (see http://www.artima.com/weblogs/viewpost.jsp?thread=173229 ). In addition to the language Java itself, those guys had to write the whole JVM, a GC and libraries for networking, multi-threading and so forth.

In the meantime Java got generics, and end of this year they will probably get proper closures. Whether these features - which are nice as such - will help Java survive is a different question.

The emergence of quality "platforms" like LLVM or even higher level ones like the JVM and maybe dot.net could really bring about cool new languages, or great features in existing ones, as language writers finally have time for it. Currently we are seeing 2 languages really gaining steam on the JVM: Clojure and Scala.

In the case of Clojure, this one guy Rich Hickey could have never written such an already pretty mature and stable language with its unique combination of features (STM, sequence abstraction, persistent data structures) in such a short period of time hadn't it been for the JVM - which gave him a GC, Unicode, multi-threading and JIT compilation, tons of runtime optimization tricks like escape analysis etc. for free, not to mention the zillions of existing Java libraries.

So my hope is that this extra abstraction layer "platform" will provide us with great new (or old) features in languages that run on top of them.

Posted 2010-06-17 12:15:02 GMT by Eugen Dück

R, a specialized language for data analysis, also allows modification and retrieval of variables in enclosing scope of a lambda function. It inherited much of its semantics from Scheme, so not surprising.

Posted 2011-01-28 22:10:02 GMT by Anonymous from 132.239.115.52

"Python resists allowing you to modify variables in the enclosing scope."

That was an annoying wart. Python 3 (and probably 2.7 as well) fixed this with the introduction of the "nonlocal" keyword.

Posted 2011-01-28 22:26:52 GMT by Anonymous from 66.116.72.114

Post a comment