SS-Lisp is an experiment I've worked on in my free time, rather sporadically, for several months.

It's a Lisp compiler that runs in a browser. It compiles Lisp to an intermediary “bytecode” and it provides a virtual machine to run the compiled code with acceptable speed (I recommend Chrome or a derivative browser for “acceptable” to stand true).

It provides an “IDE” which mimics Emacs/SLIME, via my Ymacs editor. The IDE has some interesting features, like symbol completion and cross-reference—if you used Emacs/SLIME you should feel fairly comfortable with it, though do not expect it to be that competent. ;)

While just a toy, as far as my research goes, I think it's the best one at the moment. It beats BiwaScheme by orders of magnitude in terms of speed and development environment, and most other Lisp interpreters for the browser, including my own previous attempts, are not worth mentioning—except one, which actually inspired me to work on this: http://norstrulde.org/ilge10/. Great job Eric!

Update: fellow from Germany suggested that I should rename the project, since the SS abbreviation brings up painful memories in some parts of the world... I believe he's right so I'll rename it in the following days. Any ideas for a name are welcome. :-)

Followup: done with that, the new name is “SLip”. The old URL will redirect to the new one (slip.lisperator.net).

Some time back I started working on a Lisp interpreter in JavaScript. That's because I've been going through SICP, and section 4.1 is extraordinarily inspiring—if you read that, you want to write a Scheme interpreter. Except that, being already a Common Lisp programmer, I wanted to write a Common Lisp interpreter. Or at least a tiny part of it.

The version that's published on Github right now has both static (lexical) and dynamic scope, but it's somewhat cheating. To implement dynamic scope I used JavaScript's try/finally, in order to pop dynamic bindings once a LET block that established them finished execution. However, that version has a show-stopper bug: because JavaScript doesn't have tail call optimization (and even if it would)—it ruins the stack quite easily and you can't generally do loops via recursion.

So I started a new branch (which will be on Github pretty soon); on this new version all the interpreter is implemented in “continuation-returning-style”, if I may say so—instead of calling another function, or returning a value, each expression returns a function that knows what to do next. The evaluation means to call a function, and the returned function, and the function returned from the returned function, until the cows come home. (trampoline-style)

This incidentally gave me call/cc “for free”, which is nice (I already gave up my dreams of implementing a subset of Common Lisp, so I'll implement a superset instead :-p). However dynamic variables turn out to be quite a hassle now. I don't have the luxury of using the exceptions of the underlying language, because the stack is cleared after each expression evaluates. Somehow I need to catch the moment when a scope exits, in order to restore the dynamic variables that it modified, but I'm not quite sure how—and the problem is exaggerated by having continuations... Grr, I'll think of it some more this weekend.

Anyway, I'll publish a toy Lisp environment, with an Ymacs demo for the browser. Soon. It will be totally useless for practical purposes, of course. It can solve WOTF in 10 seconds, with a Schemeish amb macro. (100 times slower than the plain JavaScript implementation).

Every now and then I keep thinking of this. What got me started to write it all down was this thread on the mailing list. Some guy who enjoys pain takes the trouble to write an E4X extension to Node (it really should be an extension to V8, but let alone that). Then another guy replies:

“We aren't interested in language features, we're building a platform and not concerning ourselves with the language and vm allows us to build and iterate on this platform significantly faster than if we were building a language.” (Mikeal Rogers)

“We aren't interested in language features”! I'm not personally a fan of E4X and don't care much about having that in the language, but I do think that JavaScript needs to evolve. When I say needs I mean right now, it's not good enough.

With minimal changes it should work on any JavaScript engine, but currently NodeJS is the main development platform.

It implements a JavaScript parser which produces a clean abstract syntax tree from JS code (this part is ported from parse-js, a great JS parser for Common Lisp). Then it contains a few functions that manipulate the AST to compress variable names to single characters, and provide various other compression techniques such as:

join consecutive var declarations:

var a = 10; var b = 20; ==> var a = 10, b = 20;

remove block brackets {} where possible

transform foo["bar"] into foo.bar

various optimizations for IF statements:

remove "else" where possible (when the last statement in an IF block is "return", "throw", "break" or "continue")

I'm writing this howto because I spent some considerable time on implementing a TCP server in CL; my lack of Lisp experience contributed to this, but also no quick guides or howtos seem to exist in this area. And an undocumented argument to a function in usocket has a default value which defeats the documented behavior, making me spend lots of time to figure out what's broken (:ready-only in usocket:wait-for-input). Poor documentation and lack of resources is a pretty bad situation for Common Lisp. :-(

The task is to write a simple TCP server class using a worker thread pool for handling the requests. There is one listener thread that clients connect to. The listener would read data from the socket, then when a full command is available for a certain client, it will send it to a worker thread to be handled. (The idea was that there could be multiple listeners as well, but at this time it's buggy.)

I submitted my Ymacs project to Ohloh (Ymacs project page at Ohloh). They have a nice feature that gives some statistics, based on the source code (they can understand some source control repositories, including Mercurial, which is what I use). The Ymacs statistics say the following (the whole source taken into consideration):

estimated effort: 4 person-years

project cost: $210,926 (for a $55000/year salary)

Counting only the JavaScript files, which is the main programming language, we have:

estimated effort: 1 person-years

project cost: $61,739 (same $55000/year salary)

The fact is: I did this myself in a bit more than 2 months (work on the website and infrastructure included).

It's true that Ymacs includes a build of DynarchLIB in it's source repository, and DynarchLIB started in 2005 (I didn't work on it full-time, though, far from it). However, Ohloh counts DynarchLIB as a single line of code, because the code is minified, so it probably doesn't add much in the 1 person-years estimation.

Once I put up a public code repository for DynarchLIB, it will be interesting to see how much Ohloh underestimates me. :-)

I just released a new project that I've been working on for about a month: Ymacs is an AJAX text editor, suitable for editing source code (currently there is support for JavaScript and XML, but more modes could be easily implemented).

Ymacs is a DynarchLIB widget, which makes it easily embeddable into any DynarchLIB application. This doesn't sound impressive, isn't it, but here's the real good news: I've decided to open source DynarchLIB and release it under a BSD-style license. Some folks might believe this project is already dead, but this isn't so; it is true that there was no new release in almost two years, but the thing kept being improved and there are people using it in successful commercial applications.

Well.. This should happen any minute, but I'm running out of time, as usual. So it could take a few more days to push a new DL release. In the mean time, go check Ymacs, it's pretty cool. It has Emacs key bindings too. ;-)

So I'm learning Common Lisp. Why would I do that? Well, for one thing, I don't have much work to do lately, which is pretty bad because it directly translates in a poor financial situation (wanna hire me?). But on the other hand, because Lisp is cool and I've long wanted to learn it. Friends of mine keep asking "What can you do with Lisp? Can you find a job? Can you make any money with it?" — I haven't got an answer to these questions yet, but one thing is certain: I can use it myself and finally replace Perl for my server-side needs.

I'm writing in this article how I solved two of the things that bothered me. It's probably not useful for experienced Lisp hackers. ;-)