Making Javascript Useful: Part 0, Taking off the Training WheelsI am growing fond of Javascript.
Javascript is a fascinating language. In this respect, most serious* languages are fairly ordinary: in the first five minutes of reading a language tutorial, you generally have a grasp of that language's big "thing".** For instance, if you are coding in Ruby, you know that Everything-is-an-Object, so you put on your Noun hat and get to work. In Python, Spacing-is-Blocks-so-you-Better-Make-Small-Modules, so you open your file manager alongside your editor. In PHP, PHP-Interoperates-With-Apache, so you open your ssh terminal and ftp client. In general, this is a "Good Thing." The unifying feature of the language helps the nascent acolyte learn the language by giving her mind something to put a handle on - a solid, defensible concept to inform and direct the learning process.
I don't want to give the impression that a language's big selling point is the language. I am not saying that these languages
are that "thing". That said, it is important to note that they almost always start that way.
With most languages, the initial concept grows on the programmer until that framework of thinking enables her to do wonderful things within the language. This almost always happens (to me at least) when I start to get a real "feel" for how the language works and know without having to look at a reference manual how it is going to handle something I haven't seen before. If you have ever known that gloating sensation of supreme competence when something new works the first time, you know what I am talking about. When you get to this stage, your abstractions become clear and concise as a matter of habit and the code almost writes itself.
Although this competence comes faster with every language I learn, it generally comes slowly over the course of several months. With Javascript, the competence came overnight, after a full nine months of learning. I'm not bragging about this: it is actually rather sad that I didn't "get it" sooner. The article that really made it click was
this one. This is the Mozilla Foundation's Core Javascript reference on Functions. If you work with javascript at all regularly, you owe it to yourself to read and understand that article.
So, have you all gone and read the article? No? Well go do so, it is quite fascinating. You disagree? I suppose you can disagree, but you might miss an important point.
"That was certainly interesting," I can hear you saying***, "but what is the point?" The point is: this is somewhat different from what you will hear about javascript in any tutorial and almost every book about the language. Most presentations of javascript that I have seen point out that javascript looks pretty much like C and leave it at that. So javascript becomes the Javascript-Is-Very-Much-Like-Java-:-That-Hip-And-Popular-Language-You-Actually-Have-Heard-About-And-We-Kinda-Look-Like-That-Too-If-You-Squint-And-Don't-Do-Anything-Too-Complicated language. So coming into javascript programming, you really have No Idea what to expect, except that it's something like C and Java, which, if you've actually used one of these languages is very obviously, poignantly untrue. Thus, you define your one-deep functions with the "function" keyword and use 'if' statements and 'for' loops as if they were the garden variety C variants of those constructs and hope for the best. Perhaps, you will brush up against something more esoteric in the cataclysmic depths of the ecmascript standard; you may notice the odd property that 'everything is a hash table.' Odd things though you may see, it doesn't really keep us from thinking about javascript as a quirky, clunky C'ish variant.
Well, what changes when you read the article? Probably nothing, if you just skimmed it. If you didn't notice it right off, try replacing the word "Function" in that article with the word "Lambda." Notice how the javascript Function object allows you do Lambda calculusy things with your code. As it turns out, in many ways, javascript has more in common with Lisp than C.
Consider the naive recursive Fibonacci number generator in "vanilla" javascript - it looks almost like the C equivalent:
function fib1( n )
{
if( n < 2 ) {
return n;
}
return fib1( n - 1 ) + fib1( n - 2 );
}
Now we can write this as a Function object:
var fib2_code = "if( n < 2 ) {return n;} return fib2( n - 1 ) + fib2( n - 2 );"
var fib2 = Function( "n", fib2_code );
Now it looks like poorly written C code. Of course, this doesn't really get us anything new or different; however, since this code is a string, we can modify it like a string, similar to the way we can edit Lisp s-expressions:
var myfunc = Function( "n", "if( n < 4 ) { return n - 2; } return n * 2;" );
var fib3_code = fib2_code.replace( /fib2/g, "myfunc" );
var fib3 = Function( "n", fib3_code );
Naturally, this is a rather silly example, but if you use your imagination, you can think of some rather clever (perhaps even devious) constructs that you can build with this technique. At the very least, it expands the "typical" javascript toolbox to include both Lisp'ish and C'ish constructs. With this realization, it should be relatively clear why I think javascript so extraordinary: Javascript combines the mathematical generality and flexibility of Lisp with the high-level ease-of-use of C.
Of course, the fun hardly ends here. I'll write an article soon that deals with some of the ramifications of these internals. As it turns out, this will have a dramatic impact on how we implement, abstract, factor, and secure our client-side code.
* - I love BrainF*ck too, but until I see a web-server written in it, it fails my litmus test for being a "serious" language.
** - I am not insulting your favorite language! I love your favorite language too! However, to an outsider, a language's big selling point _is_ the language. Bear with me.
*** - Yes, that was (almost certainly) ventriloquism.