Atlas · Details
Ejacs: a JavaScript interpreter for Emacs
Author’s note
This is a surprisingly good read from the sidelines, from someone with no longer any skin in the game. I remember the reception to my Scheme/Elisp/CL comparison was legendary; I nailed that one.
One big thing that changed after this post, much to my surprise and delight, is that Stefan Monnier took over as Emacs maintainer. He led the development of a tremendous number of new Emacs Lisp language features, bringing it much closer to parity with modern dev languages.
AI Notes
Eight months after shipping js2-mode, Steve released Ejacs — the JavaScript runtime side of the same plan, around 12,000 lines of Emacs Lisp built on a port of Mozilla's Narcissus interpreter plus a hand-rolled Ecma-262 runtime (Object, Function, Array, Math, Date, RegExp, the lot) translated straight from the spec into Elisp. In principle the combination meant an Emacs user could now write extensions in JavaScript instead of Elisp — js2-mode parsed and edited, Ejacs ran it; in practice the seam between the two never closed, but Ejacs shipped as a working ECMAScript console under a permissive license. The post itself is a small classic of Steve's late-2008 voice — opens with a long apology about ripping off his thumbnail, segues through guitar and Fallout 3 (Nuka-Cola Quantum, Blamco Mac and Cheese), then confesses he's "doing a trick this time" by writing about something he finished a year earlier. A commenter named Andrew Barry had suggested he not call it Ejacs; the name stuck.
Related listings
-
2008
js2-mode: a new JavaScript mode for Emacs
The other half of the project — the editor mode that landed eight months earlier. Same Narcissus port, same goal.
-
2008
XEmacs is Dead. Long Live XEmacs!
Same year, same Emacs sub-blog. Together with js2-mode, the three posts are Steve's snapshot of where the Emacs world stood in 2008 — and where he wanted to drag it.
-
2007
Boring Stevey Status Update
The post Ejacs name-checks — Steve had first mentioned the unnamed JavaScript interpreter for Emacs in his 'no, I have not been fired from Google' status update a year earlier.
Where it was argued
- jwz.org Nov 2008 — Jamie Zawinski — author of Lucid Emacs, the fork that became XEmacs — wrote it up: “making fun of Emacs Lisp is kind of like kicking a puppy… a puppy who’s been dead since 1981,” then quoted Steve’s Scheme / Emacs Lisp / Common Lisp car analogy in full. 19 responses.
- Hacker News Nov 2008 — The announcement thread (38 points).
From the peanut gallery
Read the rest of the thread · 47 more
-
I have absolutely no idea what you're talking about but Ejacs is the best name for a software package that I've heard in a long time. Long ago they taught in marketing 101 that the ideal product name should contain a promise - and what better promise is there to make?
-
Seems like it would be easier to turn firefox into an editor.
-
The name of the project sounds quite naughty; I'm not a fan of it, but it is undeniably catchy. It reminds me of an idea a friend once had: a graphical editor custom tailored to a problem he was trying to solve. He named it SPOOGE (Special-Purpose Object-Oriented Graphics Editor).
Needless to say, it didn't get very far. -
I also got quite far writing a javascript interpreter in javascript a while ago (or at least a reasonable subset - eg leaving out stuff like the 'with' statement).
The parser/compiler converted JS source into byte codes, for which there was a separate VM written in JS.
And then I wrote the VM in java. And then in C++.
Then I saw some butterflies...
Actually, at this point I realized there was no real commercial driver for this stuff and let it lapse.
But it was also a really good way to understand some of the low level behavior of the language.
Unfortunately this involved getting a deep understanding of the == operator. And thus a desire to punch people. -
Do you really mean it when saying "But it pretty much combines the elegance of Common Lisp
with the industrial strength of Scheme", or the opposite, i.e., "But it pretty much combines the elegance of Scheme with the industrial strength of Common Lisp
"?
Maybe I am just dumb, but I always think Scheme is THE more elegant Lisp. -
an0 said...
Do you really mean it when saying "But it pretty much combines the elegance of Common Lisp with the industrial strength of Scheme"
Yes, an0, he probably does mean it.
Scheme is elegant.
Common Lisp is industrial.
Emacs Lisp is not elegant, and not industrial. -
Looking at the list of problems I noticed that the crown jewel of object-orientation - that is: override-able methods - is not explicitly mentioned (It is just hinted at occasionally).
I think this no coincidence: Success of OO comes from other factors (e.g.: it helps in organizing the code, simplifies expressions, etc.).
I vaguely remember Steve saying something along these lines it in one of his earlier posts. I must admit I also believe in this (implicit) sentiment. -
@ano You don't get his drift.
-
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.
So, while it doesn't make Elisp suck any less at the moment, it does take away the "JS at least is being worked on" argument. And JS has a fair share of stupid crap going about it too, starting with stupidly incoherent implementations (which improves over time, but still) and ending with it being a Lisp, except with syntax and consequently no macros. -
Nice article.
I think there's another way out for Elisp, by the way -- compile it to a different target than the current Emacs runtime. I know it sounds silly in 2008, but Guile might be that runtime. It gives you modules and pthreads, standard SRFI libraries, and possibility for much more optimization (including native-code JIT).
Check the guile-devel archives for info. -
Verily.
I'm hoping that Bethesda will release modding tools soon. The -few- quest glitches and unkillable NPC's are annoying. -
Thanks, Steve. I love interactive shells, they make me smile.
BTW, David Notkin has an immense beard. Puts my whiskers to shame! -
Mark Tucker: I always enjoy seeing a reference to Why Microsoft can Blow-Off with C# here.
Almost as much as I loved the characterization of Common Lisp as "Howl's Moving Castle". I'm still laughing at that.
(Scheme isn't actually an exotic sports car. Connection Machine Lisp is the exotic sports car. As someone else I was talking to mentioned, it has a peaky, but powerful engine and a very notchy tranny that prevents you from actually using it.) -
Steve, could you please tell how long it took for you to implement the ECMA spec?
-
I've been doing some Clojure hacking lately...and yes, you *will* like it. :)
Stu Halloway has a beta Clojure book you can pick up here:
http://www.pragprog.com/titles/shcloj/programming-clojure -
Huh. I started this a while back too but don't seem to have nearly as much determination as you had.
I took an entirely different tack though. I wrote a bison grammar with elisp actions and then post-processed the bison parser into a table-based elisp parser.
I wanted to hook this into emacs-w3 to interpret javascript code on web pages so things like onclick="this.form.submit()" would work.
I had hoped if I got the interpreter basically working others would step in and implement the DOM and basic language objects. But, uh, that never happened.
Anyways, if you want to check out another attempt at the same thing look at:
http://freshmeat.net/projects/ebison/ -
I want the reciprocal, emacs in javascript (or pehaps java) so I can run it in a web browser or an Andriod cell phone.
Then again, you can just install Debian on a jailbroken android phone, so the idea may be kinda irrelivant soon. -
I'm wondering if this javascript lisp implementation will run in it...
http://joeganley.com/code/jslisp.html -
What I really want is some sort of interface between Emacs and the JVM, so we do less porting and more linking
-
You embedded Javascript into EMACS? Has nobody heard of Lua? :(
-
Mathrick is right: lexical scope has been implemented in Emacs (the lexbind branch) and is scheduled to be merged into the trunk after 23 is released, which is a few months away. Once that's in place, adding concurrency features is the next step, something that I don't think Javascript is currently targeting.
Also: elisp doesn't require an explicit "return", the requirement of which is full of fail. -
I'm so happy to hear that are other people out there who like Javascript.
-
Emacs is basically one big program soup.
Funny thing is, so is a modern web page. HTML, CSS, JavaScript--toss into a pot and stir with a Greasemonkey script. Makes you wonder if these platforms succeed so brilliantly in spite of the tangle or because of it. -
I imagine the post you hinted at writing was about Max/MSP. As a musician and a not-even-good-enough-to-call-myself-a-hobbyist programmer, I'd love to hear your take on it.
I broke my guitar thumbnail once bowling, and it hurt like hell. -
an0: you missed the joke.
seshagiri: um, maybe 200 hours? It's just a guess. I didn't really pay very close attention.
mathrick: very cool! Language improvements == awesome. Closures == double awesome.
phil: concurrency, eh? Rhino has continuations _and_ threads, and I believe SpiderMonkey also supports at least one form of concurrency in the "trusted mode" you use for extensions and plugins. So yes, JavaScript has concurrency. Just not in a browser pages. Would be unbelievably awesome to see any kind of concurrency support in Emacs.
Brendan Eich says he's been thinking about concurrency and hygienic macros for a future version of JavaScript. I think they have to get over the hump of classes and optional type annotations first, though. Sounds like they're getting close.
Agree that requiring return is full of fail. JavaScript 1.8 addresses it partially with "function closures", which are single-expression lambdas that don't require the return keyword. Example:
var square = function(x) x * x;
In general, void statements and functions are a cosmically stupid idea. -
You rock man!
By the way, I am still waiting for "A programmer's view of the Universe, part 2".
When it's coming up?
FYI: I know where you live! -
I hpoe you won't mind some anti-JS venting, Steve. I respect your opinion but these pro-JS opinion pieces irritate me, given the amount of suffering that the JavaScript meme has caused me personally.
I certainly wouldn't defend emacs-lisp as any kind of bastion of good design, but it does contain several workarounds for the problems you're describing. Clearly, you've heard of cl-macs. Haven't you used lexical-let? You can have closures in emacs-lisp if you want them. Sure, the default behavior is terrible, but you can program in a style that works (i.e. has lexical closures and encapsulation) if you want.
This is exactly the same situation as JavaScript, as far as I'm concerned. Sure, JS has lexical scoping, but the default behavior of assignment is to set a global variable, I'm sorry, "property of the 'window' object".
Let's also not forget that elisp's library mechanism is cruddy ("require" needs no enumeration of its deficiencies) but at least it's somewhat workable. Let's compare it to JavaScript's ... oh right! JavaScript has no support for libraries because it isn't a programming language, it's a macro syntax for validating your FORM tags in Netscape 2.0.
In summary: elisp is a terrible language with the tools to make it a reasonable language. JavaScript is a prison planet from which there is no escape, if you want to write programs that run in the popular runtime, i.e. "the" browser (as if there were only one, or even only a dozen, that you needed to care about). -
Dear Steve,
Thanks for your blog, a most enjoyable reading of mine nowadays.
Struggling in the Greap Elisp Swamp, I stumbled on symbol-function
Would that fit your bill for a useful debugging representation for functions in ELisp ?
Usage example:
(symbol-function 'foo)
=> (lambda nil (setq x 7))
Al. -
symbol-function is fine if it's not byte-compiled. In JavaScript, the byte-compiler remembers a token stream for the function that permits the source code to be printed back. If the elisp byte-compiler did this it would be a big improvement.
Hashes still need a print representation, and defstructs are just a mess, what with the crashing.
It sounds like some of this stuff is gradually getting fixed, though, which is nice. -
Stevey: could you indulge yourself and share with us a few more car analogies?
Interesting about Scheme: makes me wonder why there's no standard Scheme Radio out there that most users just agree on installing right after you drive it off the lot.
Also, you're makin' me want to watch more anime. :)
Anyone care to explain the Howl's Castle reference? Not sure I get it. Thanks. -
Hi Steve,
thanks for your blog and this post.
every post wants me to improve myself and share more with the world. Thanks.
"Anyone care to explain the Howl's Castle reference? Not sure I get it. Thanks."
+1. I don't understand either :-(
BR,
~A -
The Howl's Moving Castle comparison is the iridescent glowing jewel of humor in this particular post, IMHO. It refers to the eponymous Miyazaki film in which a wizard of sorts roams the countryside in a gigantic castle capable of walking about on mechanical legs. The comparison is with Common Lisp's "don't leave anything out" design.
-
Gavin, thanks. After googling around a bit and finding some images of the castle, I think I get it now.
-
Steve said: "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."
So, what would it take to do those things? At least some of the folks at the Emacs developers mailing list read your blog. Maybe you've started something. -
Most fantastic!
I thoroughly enjoyed reading this blog article. I find this blog best among all your blog essays i've read. (perhaps about 15 of them over the past year or 2)
I love emacs lisp! and i like javascript (not that much expert of it).
i enjoyed reading every word you gave about these languages.
Yeah, so much needs to be improved in emacs lisp. (and so obstinate are the emacs developers)
Lastly, thank you for Ejacs! I'm downloading it now, and sure will be having fun with it. I think the name is catchy too.
-----------------------
among your elisp criticism, i whole heartedly agree about the no namespace problem.
... (i thought i'd go over your criticism now and list my impressions on them)...
in your section “Problem #3: No delegation”. I don't quite understand what is meant, or the word delegation in the context of programing. I'll be doing some web searching readup on this now... if you do happen to edit this, perhaps in preparation for print publication down the road ... more detail or concret example would be great.
In your “Problem #4: Properties” section... i sorta understand what you mean but concrete example would be great. I don't know what splay-tree is. I'll be reading up.
On your “Problem #5: No polymorphic toString” section... i see what you are saying. For my own elisp experience, i didn't find this a problem. On the other hand, i thougth this problem is much severe in compiled langs, such as Java, C.
(Note: my elisp coding, and life time code production in general, is perhaps just 10% of your output. (if i recall correctly, i'm few years older than you though... or was it the same?...))
in my own elisp experience, i think elisp problem in order most severe to less severe, are:
• no namespace.
• lack of threads. e.g. typically you wait for emacs to finish something before it'll unfreeze.
• regex toothpick syndrom. Its regex should have its own string syntax, not embedded as string. I do a lot text processing. Even simple regex become unreadible in emacs.
• Lack of named parameters.
• lack of lexical scoping. I did not thought this is a practical problem, but now reading your article, the fact that emacs lack a namespace, i changed my mind. :D Yeah, i guess lexical scoping is critical when you write large programs.
... in your essay you mentioned elisp's lack of reader macro, and also highly praised elisp macro. In my own programing experience (mostly geometry visualization and web app backend), i never find any utility of lisp macro, and thought it is pretty much overrated by zealous lispers or lisper wannabe who came from procedural lang background just because it's something they've never seen.
Note that, lisp macro can be considered as crude beginning of term rewriting system/langs. In lisp communities, you see them get dizzy with macros all day, but in Mathematica, just about every line of code is macro a la lisp, because the lang is so-called a term rewriting system, with extensive pattern matching facilities.
... it would be great if you can give some concrete examples of how you used elisp macro. (i'll be checking it out in ejacs)
some other common criticism of elisp is lack of tail recursion, lack of continuation. I am not absolutely sure (don't fully understand the latter), but i tend to think these having little practical benefits.
Again, great article and thanks for ejacs.
Xah
∑ http://xahlee.org/
☄ -
I've been working on a homoiconic JavaScript syntax for madmen like you. Basically all you get now is hairy syntax, but that gets you macros for free. Not real macros though. And it doesn't have lambdas. But I'm still sorting that out. It would've been easier if JavaScript had symbols, but I think I'll be able to hack around it somehow.
Details at http://timcooijmans.wordpress.com/2008/11/26/if-you-wanna-taste-some-madness-unq/ -
Have you looked at JaM? You CAN have macros in JavaScript. http://blog.n01se.net/?p=8
-
This comment has been removed by the author.
-
Stevey I can't read your blog while I'm working it takes too much time. While a great read I feel kinda guilty since I'm not really working. Would you consider odiogo.com or perhaps getting Donald Sutherland to read it for us? One these guys would do I guess... http://www.collegehumor.com/video:1633395
-
Don't know what style of music you're playing but couldn't you have played your guitar with a pick? Or super-glued a pick onto your thumbnail or used this: http://www.alaskapik.com/?
Just wondering. -
concurrency in emacs is more important than it sounds. the scope of emacs network applications has been severely limited because emacs is a cooperative multitasking OS — if wanderlust or w3 hang waiting for a server response, the whole OS hangs with them (thus w3m-el — it's not that C is faster, but that you can call external apps in the background, but not internal apps!)
once emacs is true multitasking I expect lots of new applications to bloom. -
i like your blog ....
-
PLEAAASE DO IT !
emacs in js would be SOOO MUCH FUCKING GREAT !
Pleaaaaase ! -
Had you looked to Semantic package (from CEDET) that make process of parsing writing much easier?
-
Awesome. I found this blog entry on a search for "writing javascript interpreter". I'm a perl programmer (who also uses emacs, mostly for editing xml). I've been pulling together tools for webscraping and the one glaring thing lacking in the perl toolkit is a means of dealing with javascript in a more or less complete manner. WWW::Mechanize is awesome, but javascript can confuse it.
-
Hi all,
Under Windows I use for myself the script described in this article http://with-love-from-siberia.blogspot.com/2010/03/windows-scripting-command-interpreter.html. Unfortunately this article was written in Russian but Google.Translate can help to read it.
It completly was written in JScript, allows to run both JScript and VBScript scripts. It is flexible and configurable, allows to code easily the main script, allows to have the set of libraries that supported by WSH and will be linked with the resulting WSH file.
There are three mode of execution -- 1) run of an external script; 2) run of inline code (like Perl perl -e 'command'); 3) run in the console mode (like other JS-interpreters Rhino or Narwhal).
In the most cases it covers all my needs although it has some shortcomings -- there is little bug in the parsing of RegExps in the console mode. -
I have absolutely no idea what you're talking about but Ejacs is the best name for a software package that I've heard in a long time. Long ago they taught in marketing 101 that the ideal product name should contain a promise - and what better promise is there to make?
http://www.hedefnakliyat.com
Yay! Reverse psychology wins again!
And they said I would never amount to anything...
— Andrew Barry · 11:48 PM, November 16, 2008
You are a madman! Awesome. btw: js2-mode rules. Thanks,
David
— Anonymous · 11:21 PM, November 16, 2008
Common Lisp == Howl's Moving Castle is TOTALLY spot on. Perfect. I assume you laughed for hours when you came up with that one.
— Ola Bini · 9:28 AM, November 17, 2008