Chasing super

A lot of discussion around object-oriented Javascript involves finding cunning methods to get a super reference. This is sometimes a reference to the super class, the super instance, or the super version of the current method. The latest installment in an Ajaxian posting this week on work by Erik Arvidsson. It makes for an interesting enough intellectual exercise and I have full respect for anyone who can pull these things off. But as Erik himself has commented, is it really worth it? (“Once again I find that adding code to make things simpler in JS is unsuccessful. The costs for adding better ways to do things don’t pay for itself. (Except for the inherits function of course.”)

In the case of super…how useful is super – any of the types of super – in practice? In a more general sense, it seems that most discussions of OO and inheritance in Javascript focus more on mimicking the features of typical OO languages and less about how they are actually used. We’re thinking more about the design patterns of implementation – how to “do OO” – than the much more important design patterns of application.

super isn’t very useful for two reasons:

  • Inheritance is overrated.

    Inheritance is often considered the killer app of OO. In fact, the killer app is encapsulation – combining data and behaviour in a single model. Inheritance is a great feature, but it’s icing on the cake compared to the magnificence of encapsulation. Also, as the uber-uber GoF patterns book emphasised, delegation often trumps inheritance. In enterprise Java-land, this has now been firmly entrenched by the dependency injection “revolution”. The idea is basically small dumb things, loosely connected, just like the Unix philosophy and that of Web 2.0. You have a small Strategy class that does just that, and you can inject it into many and varied classes. You just wire up the dependencies, outside of both classes. What you don’t have is a whopping big monolithic class with loads of subclasses that each have their own subclasses doing different things. The delegation model relies on contract inheritance, i.e. Interfaces in Java terms, but not on behaviour inheritance. Inheritance is often confused for design-by-contract, especially in languages like C++ which don’t have an explicit Interface construct.

    The popularity of tools supporting delegation and dependency injection, Spring in particular, means many developers are learning this principle by sheer osmosis if not explicitly. Likewise, the duck typing of languages like Ruby and Python – and, notably for our purposes, Javascript – means you can do this stuff well without any special frameworks. Furthermore, even with Ajax starting to reach some level of maturity, most Ajax apps are orders of magnitude smaller than those enterprise apps whose complexity is a key motivation for inheritance. Inheritance? Good, very good…but overrated.

  • super is a code smell.

    For those occasions when inheritance is appropriate, super still remains inappropriate in most cases. If you take a gander at the aforementioned GoF patterns, you’ll see that most inheritance-related patterns rely on the superclass calling particular methods on the subclass (usually protected methods). These are methods the superclass has explicitly defined and knows about. As long as the protected method fulfills its contract correctly, everything works nicely. There’s no need to call super.

The more fundamental point here? Javascript ain’t Java! Every language is unique.

Reading Open-Source Code

Dave Crane looks into some Scriptaculous code. The main point is that Scriptaculous is easy for novice JS programmers to use, but the source code would be difficult, for novices at least, to understand. Which raises these questions:

So, going back to the bigger picture, here’s something for the authors of JavaScript libraries to consider. How much of a gap are you creating between using your library, and being able to modify or enhance it? Does such a gap present a barrier to its uptake? Should good code be there to be read as well as executed?

In theory, the implementation of a library shouldn’t matter to developers using it. That’s because a good library should offer components that are open for extension, but closed for modification – the open-closed principle. Thus, you should be able to treat the library as a black-box and only care about the API it presents – you never have to maintain it, so why read the code?

But it’s usually not so simple. You might not need to change the code, but you do need to understand it. In an ideal world, there would be abundant documentation. But agile says that all that documentation is valuable, but self-documenting code is much more valuable. In similar vein, the availability of code is often justified as a reason for open-source projects to include less documentation (among other benefits). So open-source code had better be understandable, ideally self-documenting, but at least well-commented.

I have used (by “used”, I mean “wrestled against in a cage match”) a couple of very prominent Java EE frameworks where implementation code is confusing and badly in need of refactoring, with most of the code comments in “TODO” and “Weren’t you going to fix this?” territory. I was stuck and documentation was insufficient, so I could only turn to the source code for help. And that’s actually a pretty good place to work out what’s going on anyway. But, alas, the code did not come to my aid. ** Perhaps that’s the natural consequence of an open-source project becoming a startup with a support-based revenue model, but it makes a mockery of the code-as-documentation argument for open-source.**

The Scriptaculous implementation is good for anyone who knows Javascript, which is all you could hope for … just because it’s API is simple enough for novices, doesn’t mean its implementation has to be. In fact, the implementations of “Puff”, “Fade”, and so on, are actually extensions of the base functionality, and any developer could create their own effects in the same way. The Effect framework is an example of how Javascript can provide decent support for Domain-Specific Languages, in Scriptaculous’s case, a grammar of visual effects. Also, if only want to use an existing effect, but with a little variation, some of them accept an options specification.