Tuesday, April 15, 2008

JavaScript 1.0 vs JavaScript 2.0 / Prototypes vs Classes

Yesterday I wrote about Google Gears vs. Adobe Air. And I talked about the fact that in my view the current version of JavaScript, version 1.7, is in my view archaic. I also erroneously stated that it wasn't object-oriented. Technically, it is but in a funky totally non mainstream way that in my view brings none of the structure or reusability of real object-oriented programming.

As a bit if history, I come to this discussion because after my old company, Clickradio, I had not been hands on cutting code for a few years. I was deciding on my toolset, and I was convinced that Flash was a platform that I could actually use to make apps that ran on the web, but felt like real applications instead of web pages. This was in around 2003.

This was a time when Flash was based around JavaScript 1.x, or more accurately ECMAscript-262, though in the Flash world it was called ActionScript. Looking back it seemed so powerful compared to what was possible with HTML and JavaScript in the browser.

I came to Flash though, at the end of the ActionScript 1.0 life cycle. Adobe (Macromedia at the time) was brining out ActionScript 2.0. We referred to the languages as AS1 and AS2. So I was in a position to observe and participate in the transition from AS1, which is prototype based, to AS2, which is class based.

If you are not familiar with the concepts of prototype based languages you can read this.

Now I don't want to get into a philosophical argument about which is "better". Because it is entirely possible for one person to reasonably like something, and another person to not like it. But to me one point is perfectly clear. The community was *radically* more productive once AS2 was introduced and people began using it. I was an active member of the Flash community at the time and it was as if the heavens opened up and people were able to do things that before hand were conceptually much more difficult. Code reuse exploded. The entire community felt empowered.

The problem with AS1 is that it encourages spaghetti code. It is indeed possible in any language to write good or bad code, but a language either pushes you in the right direction or the wrong direction. As I have argued many times before on this blog, abstractions are important. It may be possible to do anything with anything, but the way a tool is designed does matter. It is not a zero sum game. And so the argument that you *can* do something with a given tool is fairly meaningless. In fact given the vagaries of being human, the only way of measuring productivity of something like a language is to give it to people and see what happens. And indeed when we did this with AS1 and AS2, the verdict was clear. Class based AS2 was *far* more productive that prototype based AS1.

I find it almost funny to need to say these things out loud, but since I am not part of the JavaScript community I had no idea there were actually people who like it the way it is. I have been following Brendan Eich, the original author of JavaScript, and I know he is anxious to move to the new JavaScript called Tamarin, donated by Adobe. Tamarin is in the current version of Flash and is also known as ActionScript 3. I thought the only real resistance to the upgrade was Microsoft who would like to ankle any real progress in the browser, particularly when it is really powered by Adobe's technology. But I guess, no matter what venue, change is always scary.

In any case, in my view the core issue is community productivity. And it is clear that in this regard prototype based objects are not as productive measured on a community wide basis. Moreover when people have a choice, they choose classes. None of the AIR apps I am familiar with use HTML/JavaScript - though they could, and there are no Gears apps at all to speak of. I am sure there are examples in both cases but they are precious few.

So while people are arguing that prototype based JavaScript is great, it is interesting to note that in situations where there is an alternative, whether that is AS2/AS3, or AIR, or Gears, the old school prototype style JavaScript tends to lose.

JavaScript is indeed very popular right now. But only in areas where there is no other choice. Can you say Stockholm Syndrome?

6 comments:

chuck said...

I find it interesting that you invoke a psychological concept like Stockholm Syndrome as explanation of the popularity of prototypal Javascript. I think it's just as easy to argue that the reason people choose class-based object orientation when given a choice is because it's what they're used to. The "JavaSchools" phenomenon has seen to it that a generation of programmers have "learned" that "object orientation" means what Java's version of object orientation is; most have had had little to no exposure to any other. Going to a prototypal object system, or something like CLOS, to this generation of programmer, means having to step out of a familiar comfort zone and learn weird new stuff. People don't choose class-based OO because it's better, they choose it because it's familiar; and the reason why they would tend to be more productive with class-based OO than another kind, at least at first, is that they already climbed the learning curve of it back in college.

It's worth mentioning that ActionScript 2.0's object system was merely a syntactic abstraction that compiled down to prototypal AS1 -- an attempt to implement class-based OO in terms of prototypal OO -- and while this made the basics more familiar to programmers without a Javascript or AS1 background, there were serious leaks in that abstraction that made for several rather ugly warts in the type system and memory usage, some of which only started to make some sense once you took the time to understand the underlying prototype model.

AS3 was a total re-do of the engine, and does much better at class-based OO, but some of the dynamism that was lost is understandably missed by some folks who worked with AS1 or Javascript enough to actually learn prototypal OO. In many ways though, it strikes a pretty nice sweet spot: optional type checking, object literals, functions as first-class values, and optional dynamic objects are among its really nice, somewhat underappreciated features.

Old-school Javascript/AS1 "encourages" spaghetti code insofar as most programmers working in it are novices at prototypal OO, hamstrung by preconceptions of what OO is supposed to be, and/or just winging it. But this is just how it is when people work with an unfamiliar tool. There was plenty of awful spagetti code in AS2, written by people more used to AS1 idioms, using techniques that were good in AS1 but turned into a mess when jammed into the AS2 mold.

Prototypal OO has a lot to recommend it technically when you approach it on its own terms. It has a high degree of "lispy" design freedom, but with freedom comes responsibility; programmers unaccustomed to it are liable to be irresponsible with it. That's not necessarily the fault of the language or the conceptual model it's based on, however.

Hank Williams said...

@ chuck

Actually the AS1 to AS2 transition is particularly interesting in that most of the people transitioning did not have classical schooling to inform their opinions. So the transition was a particularly good test of whether the prototype or class model was more productive in that it tested people that had *lots* of prototype experience and generally no traditional schooling in class based OO. And yes, AS2 compiled down to AS2. It was an abstraction. That doesnt in any way inform the argument about the fact that AS2 was *far* more productive for most of these people even though they had to entirely change their way of work.

Hank Williams said...

@Chuck

one more thought regarding this:

"Prototypal OO has a lot to recommend it technically when you approach it on its own terms. It has a high degree of "lispy" design freedom, but with freedom comes responsibility; programmers unaccustomed to it are liable to be irresponsible with it. That's not necessarily the fault of the language or the conceptual model it's based on, however."

Languages do not have "faults" just characteristics. This is why I frame the argument in terms of general productivity. It is clear empirically, it is more productive for most people, but almost certainly not for all. But if the goal of a platform is to maximize productivity within that platform, you want the language that provides overall the most productivity. You mileage may vary on an individual basis.

Sasha Chedygov said...

I agree with the fact that people use JavaScript just because they have to, and after a while they get used to it. If Python was all of a sudden magically supported in every browser, I can guarantee that at least 25% of all JS developers would switch to it.

I think it's one of those things were since people get so much freedom in JavaScript, they tend to want to use it, and that's what causes the problems. Python, for instance, is a fairly strict language compared to JS, but the code is just so easy to read (and write). If you wrote an app in Python and the same app in JS, any developer would be able to tell exactly what the Python one does after skimming over it. I can't guarantee anything like that with JavaScript.

@chuck
"It's worth mentioning that ActionScript 2.0's object system was merely a syntactic abstraction that compiled down to prototypal AS1..."

Isn't that the point? Hank is arguing that abstraction is good. It doesn't matter what it compiles down to. What matters is the language itself, and how clean and productive it is.

chuck said...

@sasha: That's not quite the point I was making, though: what I was getting at was that the abstraction in question, that is, class-based OO, would have worked better in AS2 had the abstraction plugged in at a lower level. Rather than a new system geared towards a class-based language, AS2 tried to implement classes as a coat of paint over top of prototypes, and in a lot of ways, it sucked, as a consequence, and definitely by comparison with AS3. AS1 was fairly good at being what it was intended to be, as is AS3, but AS2 had a personality crisis.

Come to think of it though, AS1/Javascript has a personality crisis of its own. The language was designed to try to feel familiar to Java programmers, so to a degree the syntax was designed around trying to make the programmer feel like they were still working with classes. So Javascript also suffers from trying to hide its true prototype-based nature, and I do think that the results are frequently confusing. Had the syntax been designed to be more explicitly prototype-based like Self or Io, I wonder whether the programmer productivity difference Hank is observing would still be there.

Python in browsers would be sweet :D

slip777 said...

Well, from my experience (not as big to write this kind of conclusion) the people who's skills I trust were giving mostly positive feedback about JavaScript, and the people who couldn't manage to write good stuff are always complaining. Of course the language isn't perfect, but name which one is? I fully agree with Chuck - most of the articles out there about "JavaScript programming" or "patterns" are about "How to make class inheritance work" or "How to implement private memeber", so even vendors of the language started speaking in the terms of Java referencing functions and prototypes as classes and inheritance. Which is sad, cause it's like "oh we are forced to write in this stupid language, so instead of learning how to program in it lets make it behave like Java, the language we used to". I'm even currently working in the company that once ago said - "this is such a stupid language, let's create an AJAX framework that has XML based language", and now they are breaking their heads to migrate the huge framework to the solution which would use JS instead.

Like hundreds time I hear it's not an OOP language, but please tell me which one of the core OOP principles - abstraction, encapsulation, inheritance or polymorphism - says word "class"? All of them perfectly fit into prototypical paradigm, unless you can name me which not. It's alrady a long time ago people start thinking - if we call it OOP, then maybe it means that main concept is object.

I have worked on code bases writen in Java, and of course there were brilliant solutions, but 80% of code I read till this moment are so overbloated with huge unreadable and unmanagable classes, which have nothing to do with real world concepts they try to represent.

I like Python, great language, very expressive and very flexible. I would gladly add many of it's features to JS, but again (well I had read not much code, but) being the Python coder doesn't make you a good coder. I still often saw spagetti messy code. Still one of the languages in my top 10.

I never programmed ActionScript, but I knew some people who did, and after the AS2 most of them actually stopped working with the technology, rest were complaining that Adobe spoiled the language.

So sorry, I don't know where you taking your statistics from :/

So maybe the problem with spagetti code is not the problem of this language in particular? Maybe it's like already many decades that people write crap all over the world, although there are like hundreds of powerful theories for abstraction and code reusage, not only classification? Maybe people are just too lazy to learn new things? Class based programming was and is predominant for a very long time (I wasn't even born then), so if you wanted to program you had to know it, and I wouldn't say because it was the best choice (there are so many examples in software development when quality, reliability, efectivenes, readability, etc. were thrown away due to lazyness). Now the mainstream didn't changed, so nothing will force you to learn something new. How do you think how many people programming JS actually tried to read papers on Self programming language, dive into the aspects and techniques of explorative programming, studied the lambda calculus, read any papers on the family resemblence in psychology and programming, studied the object modeling pretty deeply?

ANd in the end classification was never a native thing for a human to do. It was always a harmful and hard process for the human, and always ended up in ten different classifications of one and the same thing by ten different people. Psychologist noticed that already a long time ago, so I think it's only a metter of time when the software tasks become complex enough (I think they already are) for the class based programming to fail to work for the team of people with different visions on how to clasify same objects (objects themselves stay the same in everyones vision ;) ).

Post a Comment