Clamato: A Smalltalk Dialect for Javascript
clamato.net
clamato.net
(1) How suitable is JS for use as an object code?
(2) Is this trend taken into account by those designing the future of JS?
Highly. I think it's a much nicer language to compile to than to write by hand (although JS is a pretty good language), especially if you want to use a very high-level language and have your code run in a web browser. We compile to JS from Common Lisp using a set of macros built on top of the excellent Parenscript library. We've built things up incrementally to the point that we're now able to write most of our app in a subset of Common Lisp that compiles to efficient JS. The other day I took some Lisp code I wrote a year ago and generated JS from it without having to change it. That's the first time that's happened. (We'll probably open-source this eventually as a layer on top of Parenscript.)
A big advantage of this approach over JS libraries is that you can emit quite low-level JS, so you don't have to pay for all that abstraction at runtime.
Having said the above, I'll partly take it back. JS isn't completely object code in the sense that you can generate it and forget about it. You need to be able to debug it in the web browser, and that means you need to be able to read it. In that sense, it's not really object code.
I'm pretty sure it must be possible to 1. preserve the "semantic trace" of compilation from high-level Lisp to low-level JS and then 2. write a high-level debugger that, given a piece of object-code that went wrong, points to the high-level code that generated it.
A complete solution might be intractable but even a partial solution could greatly help debugging.
When the JS engine throws a runtime error it typically (depending on the engine) includes line/char pos for the point of error. A wrapper then extract line/char from the error message, finds the corresponding position in the original source, and displays that also. This greatly helps debugging runtime errors.
It is not perfect, since some engines (e.g. Rhino) doesn't include position for runtime errors.
I've built two primary compiler projects targeting JS, a Python->JS compiler and a 6502 emulator that dynarec's to JS. Both were easy to build and its flexible nature made everything work out very well. I dislike writing JS myself (just don't dig the syntax), but writing compilers backending to it works out quite well.
I find it too high-level, with insufficient control over the lower-level details. For Skulpt (my Python-in-JS implementation) it works "ok" because JS and Python are similar in some respects, so some things map pretty well. But, for other things, like implementing longs (aka bigint), or implementing exceptions and attribute lookup faithfully to Python's semantics, it requires overhead that I consider unnecessary. Control structures from more flexible languages would require extensive hoop-jumping too.
Really, JVM-in-browser was the "right" solution, but the implementation of that is obviously horrible and impractical.
Not sure about #2, I guess it's a chicken-and-egg problem. With Google compiling from Java there should be some motivation to improve that use-case.
The scoping rules combined with the distinction between expressions and statements means that it is harder to generate composable snippets. For example you cannot just generate a small "context free" code snippet with a local variable - the scope of a variable is always the function, so you need either to mangle the name to create a unique variable, or create an inline function and call it - but that changes the semantics of return, which again is a hindrance to composability.
I would definitely prefer something like scheme as a compilation target, but it could be a lot worse. Imagine compiling to VBScript :-)
For my particular project which compiles ES5/Harmony to JavaScript it works quite well, but those languages are based on JavaScript anyway, so that is almost cheating.
(2) AFAIK the working group are a aware of the interest in JS a compilation target, but are not at the time considering adding features specifically to make it more suitable for that purpose.
asdfiojafdiojafdsooijfa
Anyway, thanks, this is awesome.
I thought you Canadians were better than that. shakes head
Either way, it's a prevalent drink in Canada and difficult or impossible to find elsewhere.
I can live with no metaclasses. Special syntax for instance variables isn't that much of a problem. 0-based indexing -- this should be easy to take care of with your own collection classes.
However, no explicit returns -- this one kills me.
I guess this has to do with Javascript.
EDIT: JS has exception handling, so this could be used to implement explicit returns.
self return: [:ret | .... ret value: foo ...].
But you only pay the cost of the try/catch/throw when you actually use it.
FWIW, I've found that the lack of explicit returns really isn't a problem, at least in the code I've written and ported so far.
But you only pay the cost of the try/catch/throw when you actually use it.
Do you mean that the existence of an explicit return is recognized at compile time, so only the functions that actually contain one need to be wrapped in a try-catch? Now that I think of it, that seems like the best way to do it. I've wanted to be able to compile return-from into JS for a while...
Also, please join to Clamato google group: http://groups.google.com/group/clamato-smalltalk/
After some recent ambitious JS development, it's become clear to me that the language is just unsuited to large scale development and no library is going to change that.
As such, I am really keen on these compiler projects, but I think it's a mistake to avoid language features because they are difficult to implement in JS. Syntax is nice, but it's those language features that are really needed.
I get a generic "Error committing to counter.st" when I try to follow the tutorial though right now, using Chromium nightly on Ubuntu.
(Trying to think of a project that could be called Caesar... ;)
edit: oops, can't read: the browser's already called Caesar.
You should be able to just ignore the commit errors and keep going through the tutorial, I think? But to get rid of them, just search for the "save" method, and remove the line that says "self commit", and then save it.
It's probably the DOM manipulation specifically. Are you adding the results in one big innerHTML assignment?
You can also try breaking the search into small chunks with setTimeouts between them.