This link has been bookmarked by 26 people . It was first bookmarked on 17 Nov 2008, by someone privately.
-
16 Jun 18
-
05 Aug 11
-
26 May 11
-
- Emacs Lisp vs. JavaScript
- Scheme is an exotic sports car. Fast. Manual transmission. No radio.
- Emacs Lisp is a 1984 Subaru GL 4WD: "the car that's always in front of you."
- Common Lisp is Howl's Moving Castle.
In the interests of having something resembling original worthwhile content today, I'll do a little comparison of Emacs Lisp and JavaScript. I know a lot about both languages now, and a few folks mentioned that a comparison would be potentially interesting.
Especially since I think JavaScript is a better language.
So... the best way to compare programming languages is by analogy to cars. Lisp is a whole family of languages, and can be broken down approximately as follows:
-
-
27 Oct 10
-
19 Dec 08
aminggs"Anyway, here's the comparison. Here's why I think JavaScript is a better language than Emacs Lisp.
/
Problem #1: Momentum;
Problem #2: No encapsulation;
Problem #3: No delegation;
Problem #4: Properties;
Problem #5: No polymorphic toString;
Emacs advantadocument article blog steve-yegge ejacs interpreter emacs lisp elisp javascript comparison languagedesign import:delicious
-
14 Dec 08
-
28 Nov 08
-
26 Nov 08
Tim Lossen"... all Lisps have their attractions, and yet each also has a niche. You can choose a Lisp for the busy person, a Lisp for someone without much time, or a Lisp for the dedicated hobbyist, and you'll find that no matter which one you choose, it's missing
-
20 Nov 08
-
19 Nov 08
-
18 Nov 08
-
17 Nov 08
-
Here's why I think JavaScript is a better language than Emacs Lisp
-
A recurring theme is that Elisp and JavaScript both will both exhibit a particular problem, and there are specific near-term plans to fix it in JavaScript, but no long-term plans to fix it in Elisp.
-
Every symbol in Emacs-Lisp is in the global namespace. There is rudimentary support for hand-rolled namespaces using obarrays, but there's no equivalent to Common Lisp's
in-package, making obarrays effectively useless as a tool for code isolation.
The only effective workaround for this problem is to prefix every symbol with the package name. -
Emacs-Lisp more difficult to read and write than Common Lisp or Scheme
-
JavaScript also lacks namespaces. They're being added in ES/Harmony, but in the meantime, browser JavaScript code typically uses the same name-prefixing practice as Emacs-Lisp.
However, JavaScript has lexical closures, which provide a mechanism for creating private names. One common encapsulation idiom in browser JavaScript is to wrap a code unit in an anonymous lambda, so that all the functions in the code unit become nested functions that close lexically over the top-level names in the anonymous lambda. -
elisp is not lexically scoped and has no closures
-
let-bound variables in elisp can still be destroyed by your callee: a dangerous situation at best
-
One of the big advantages to object-oriented programming is that there is both syntactic support and runtime support for automatic delegation to a "supertype". You can specialize a type and delegate some of the functionality to the base type. Call it virtual methods or prototype inheritance or whatever you like; most successful languages support some notion of automatic delegation.
Emacs Lisp is a lot like ANSI C: it gives you arrays, structs and functions. You don't get pointers, but you do get garbage collection and good support for linked lists, so it's roughly a wash.
For any sufficiently large program, you need delegation. In Ejacs I wound up having to implement my own virtual method tables, because JavaScript objects inherit fromObject(and in some cases,Function, which inherits fromObject).
Writing your own virtual method dispatch is just not something you should have to do in 2008. -
JavaScript is fundamentally a properties-based language, and it's really nice to be able to just slap named properties on things when you need a place to store data.
Emacs Lisp only offers properties in the form of simple plists – linked lists where the odd entries are names and the even entries are values. Symbols have plists, and symbols operate a little bit like very lightweight Java classes (in that they're in the global namespace), but that only gets you so far. If you want the full JavaScript implementation of the Properties Pattern, you'll have to write a lot of code. -
Emacs has hashtables, but they're heavyweight: if you try to instantiate thousands of them it slows Emacs to a crawl. So they're no good for the default
Objectproperty list. Emacs also has associative arrays (alists), but their performance is O(n), making them no good for objects with more than maybe 30 or 40 properties. -
people have ported subsets of CLOS to Emacs Lisp, but I've always found them a bit clunky. And even in CLOS it's hard to implement the Properties Pattern. You don't get it by default. CLOS has lots of support for compile-time slots and virtual dispatch, but very little support for dynamic properties. It's not terribly hard to build in, but that's my point: for something that fundamental, you don't want to have to build it.
-
One of the great strengths of JavaScript is the
toSourceextension. I don't know if they support it over in IE-land; I haven't been a tourist there in a very long time. But in real versions of JavaScript, every object can serialize itself to source, which can then be eval'ed back to construct the original object.
This is even true for functions! A function in JavaScript can print its own source code. This is an amazingly powerful feature. -
in Emacs Lisp, many built-in types (notably hashtables and functions) do NOT have a way to serialize back as source code. This is a serious omission.
-
If you want a debug dump of a data structure, you write a function to do it. But Emacs provides a half-assed solution: it debug-prints lists very nicely, even detecting cycles and using the #-syntax for representing graph structures (as does SpiderMonkey/JavaScript). But it has no useful debugging representation for hashtables, functions, buffers or other built-in structures, and there's no way to install your own custom printer so that the debugger and other subsystems will use it.
So it sucks. Printing data structures in Emacs just sucks.
The situation in Ecma-262-compliant JavaScript really isn't that much better, although you can at least install your owntoStringon the built-ins. But any competent "server-side" JavaScript implementation (i.e. one designed for writing real apps, rather than securely scripting browser pages) has a way to define your own non-enumerable properties, so you can usually override the default behavior for things liketoStringandtoSource. -
Pound for pound, Emacs Lisp seems roughly as expressive as JavaScript or Java for writing everyday code. It shouldn't be that way. Emacs Lisp ought to be more succinct because it's Lisp, but it's incredibly verbose because of the namespace problem, and it's also verbose to the extent that you want to use the properties pattern without worrying about alist or hashtable performance.
-
Elisp does have a few places where it shines, though. One of them is the
cl(Common Lisp emulation) package, which provides a whole bunch of goodies that make Elisp actually usable for real work. Defstruct and the loop macro are especially noteworthy standouts.
Some programmers are still operating under the (ancient? legacy?) assumption that theclpackage is somehow deprecated or distasteful or something. They're just being silly; don't listen to them. Practicality should be the ONLY consideration.
Theclpackage wouldn't have been possible without macros. JavaScript has no macros, so even though it has better support for lambdas, closures, and even (in some versions) continuations, there are still copy/paste compression problems you can't solve in JavaScript. -
Emacs Lisp has
defmacro, which makes up for a LOT of its deficiencies. However, it really only has one flavor. Ideally, at the very least, it should support reader macros. The Emacs documentation says they were left out because they felt it wasn't worth it. Who are they to make the call? It's the users who need them. Implementer convenience is a pretty lame metric for deciding whether to support a feature, especially after 20 years of people asking for it. -
Elisp is s-expression based, which is a mixed bag. It has some advantages, no question. However, it fares poorly in two very common domains: object property access, and algebraic expressions.
JavaScript is NOT s-expression based (or it wouldn't be a successful language, many would argue), but it does offer some of the benefits of s-expressions. JSON is one such benefit. JavaScript's declarative object literals (or as a Lisp person would say, "syntax for hashes") and arrays provide a powerful mechanism for designing and walking your own declarative data structures.
JavaScript also has all the usual (which is to say, expected) support for algebraic operators. And unlike Java, JavaScript even got the precedence right, so it's not full of redundant parentheses. -
I've now written at least 30,000 lines of serious code in both Emacs Lisp and JavaScript, which pales next to the 750,000 or so lines of Java I've crapped out, and doesn't even compare to the amount of C, Python, assembly language or other stuff I've written.
-
30,000 lines is a pretty good hunk of code for getting to know a language. Especially if you're writing an interpreter for one language in another language: you wind up knowing both better than you ever wanted to know them.
And I prefer JavaScript over Emacs Lisp. -
I suspect I would probably prefer Clojure over Rhino, if I ever get a chance to sit down with the durn thing and use it, so it's not so much "JavaScript vs. Lisp" as it is vs. Emacs Lisp.
-
I would love to see Emacs Lisp get reader macros, closures, some namespace support, and the ability to install your own print functions. This reasonably small set of features would be a huge step in usability.
-
I've found that JavaScript is a language that smart people like. It's weird, but I keep meeting really really smart people, folks who (unlike me) are actually intelligent, and they like JavaScript. They're always a little defensive about it, and almost a little embarrassed to admit it. But they think of it as an elegant, powerful, slightly flawed but quite enjoyable little language.
-
A little bird told me that Elisp *is* actually being worked on; apparently it's going to grow lexical scoping and coroutines in the foreseeable future. Can't remember if there were plans for packages now. And that is disregarding all the smaller and more trivial fixes it regularly gets.
-
-
sdagueSo... the best way to compare programming languages is by analogy to cars. Lisp is a whole family of languages, and can be broken down approximately as follows:
* Scheme is an exotic sports car. Fast. Manual transmission. No radio.
* Emacs Lisp i
Would you like to comment?
Join Diigo for a free account, or sign in if you are already a member.