features for es that would make it a perfect intermediate compiler target

Luke Kenneth Casson Leighton lkcl at lkcl.net
Sat Mar 21 15:16:06 PDT 2009


folks, hi,

i'm the lead developer on a project called pyjamas - http://pyjs.org -
which is a python-to-javascript compiler intended to help web
developers write ajax apps in the high level language which they are
more familiar (python).  it's a port of GWT, which is for java web
developers, and there's also another port called RubyJS (see
rubyforge.org).  this helps _web_ developers but there is an
interesting thing happening when you combine e.g. a
<highlevellanguage>-to-javascript compiler with something like the JIT
javascript compiler e.g. google's V8: you get a whopping _tenfold_
performance increase over the use of the standard interpreter (e.g.
/usr/bin/python).

unfortunately, there are some absolutely horrible things in emcascript
that put it out of contention as a serious possibility for use as an
intermediate compiler target, and these i thought it would be ...
perhaps a good idea to raise with you.

as you're probably aware, python is actually a stunningly good fit for
javascript, as things like this demonstrate:
http://code.google.com/p/browsersync/source/browse/trunk/client/lib/lang.js?r=5
it gives a simple demonstration of how python-like language features
can be emulated in javascript, BUT - there are some absolutely _awful_
things that mean that javascript cannot in any way be taken seriously,
until these are fixed:

1) lack of integers.

i noted this - http://wiki.ecmascript.org/doku.php?id=proposals:numbers
- and went "thank _god_ for that".  hooray.  python "Long" can be
emulated by an object, but the lack of integers makes for _serious_
performance problems.  implementing integers as an object, and having
to add mul, add, sub, div etc. and then use Round() on _every_ input
parameter and _every_ return result?  hello? knock-knock, lights on,
nobody home? :)

btw - do give serious consideration to adding 64-bit int to the new
standard: if you're going to add 32-bit, why not throw in 64-bit int
and uint while you're at it: this _is_ 2009, and this standard will
have to be around for another... what... 10-20 years, and only 32-bit
is going to look _really_ foolish in 10 years time.

2) undefined.

specifically, the lack of exception raising when an undefined variable
is encountered.  that is _such_ a disaster it's unreal.  think about
how a compiler of a dynamic language such as scheme, ruby and python
has to emulate that, by checking _every_ single variable in _every_
single instance where it is used (and raise an exception), and you
start to realise "oh my god - that's... _awful_".

3) lack of threading / asynchronous primitives

the threading doesn't even have to be "proper threads" - but you _do_
have to have the ability to create multiple simultaneous execution
streams and allow blocking (mutex, semaphore), even if the
specification says that implementors can (or even _must_) make the
threads effectively "emulated" by a single process, so that there can
never be any race-condition issues.

asynchronous timers are _not_, on their own, sufficient.

the issue is best illustrated as follows: if you try searching for
"javascript sleep" you will find some absolutely _dreadful_ ways in
which people are endeavouring to create synchronous "sleep" functions.
 one person came up with the idea of executing a hidden modal dialog
box, using window.open("javascript:function { createTimer(...) }")
which does actually work, if you are using IE only.  everyone else
puts the browser into a tight 100%cpu hogging while loop with a timer
on the outside, to break the loop.

why are people _doing_ this to themselves?

well, they want multiple execution paths and in particular they want a
main application to wait whilst some background asynchronous HTTP task
goes off and fetches some script, or some CSS, or whatever.

in the pyjamas compiled code, the emulation of the module "import"
capability should _synchronously_ perform the load of the module, but
the only cross-browser method which is successful is to add a
< script > node to the DOM model of browsers.

the only way to "cope" with the asynchronous nature of dynamic script
loading in browsers, thanks to the lack of proper threading semantics,
is - get this: to emulate a function execution stack i.e. to begin to
emulate features of _real_ CPUs - in javascript!  i mean, that's just
... _insane_ - but it's the only way.  by emulating a function stack,
storing all local variables being used by the current function, it
would be possible to temporarily suspend "execution" of the current
application at the right point, wait for the asynchronous < script >
load to complete, and then tell the "emulator" to carry on where it
left off.  and, because all of the execution would be taking place on
an emulated function-call stack, rather than a _real_ javascript
function-call stack, this would be feasible.

i don't even want to imagine the nastiness involved in fitting python
exception handling into that.  again, surprisingly, "standard"
javascript exception handling provides just enough to emulate standard
python exception handling, correctly, but... on top of a function
execution stack, i'm not so sure.

* occasional loss of bindings of objects with their functions.

see "bind" and "partial" in:
http://code.google.com/p/browsersync/source/browse/trunk/client/lib/lang.js

the issue is that simply returning a pointer to a function does not
implicitly carry over the context - the object - with which that
function is associated, so what people do is return _wrapper_
functions that "apply" the arguments to the object.  but the thing
is... people do this _everywhere_!!!  not just once, but countless
thousands of times.

from what i gather, this has been addressed with the new "class"
system?  if you declare a class, and pass around a pointer to a
function of an instance of that class, the object goes with it,
automatically, yes?


anyway - those are the major things.  in order of priority, i'd put
them as "undefined" is _absolute_ paramount importance: javascript is
literally a total failure without concrete support from the language
itself for exception-raising on undefined variables; "integer" is
next; the asynchronicity / threading and lack of mutex and semaphores
is next (or tied 3rd-equal with integer); and the binding issue is
last on the priorities, as it _can_ be dealt with (just).

i'd be interested to hear how these issues can be addressed, using the
new language features, so that javascript can become a language that
can be taken seriously instead of being treated as something that
people avoid at all costs [silverlight, anyone?]

l.


More information about the Es-discuss mailing list