Function-ality

Posted by: Alex Russell on 10/06/2011

I’m sitting here in Derek Featherstone’s amazing a11y talk at Fronteers and I feel like I need to follow up the last post with a quick primer on the zen of function for (both of) the spec authors who read this blog.

The reason it’s offensive to the JS hacker for WebIDL to disallow new against DOM types — any of them — is that it means that it’s no longer specifying how you’d describe these types in the primitive we use over here in JS for this sort of thing: functions. This might sound nuts to folks who come from C++ or who spend their time in spec-ese, but there’s no difference between a plain-old function, a “constructor”, and a “partial” or “mixin” in JS semantics. We use functions for all of them. You can say new function(){ ... } and create an instance of an anonymous “class” in JS. You can take the same function and invoke it as a “regular function” — (function(){ ... })(); — and you can use that sort of function as a mixin or partial interface too: new function(){ (function(){ ... }).call(this); ... }. The exact same function object can even act in all of these capacities (although it’s rare). People use them as they need to, but they all boil down to functions.

What, then, does it mean for something to disallow new against some type for which you can in some otherwise get an instance in JS? The same thing when you can’t .call() it: it’s alien. It’s not a class as we know it, which means that it’s not a function, and if it’s not a function…well, it doesn’t belong. Fundamentally, it’s smuggling static semantics into a language that has perfectly good dynamic semantics for the same thing. This strikes at the very heart of what WebIDL is supposed to be for: describing JS types for things implemented somewhere else. By not allowing new and .call() WebIDL is giving JS semantics the bird, asserting that the fact that these things aren’t JS types makes them better in some way…and that is a bug, either in the perspective of the spec authors or of the specs themselves.

Luckily, the fix is easy: all WebIDL types should de-sugar to functions. All of them. All the time. No questions asked. That you will be able to use new and .call() and all the rest isn’t a bug, and it’s not something to guard against. It’s just how JavaScript rolls…and how JavaScript’s largest, most important library should roll too.


About Alex Russell

Alex Russell

Alex Russell served as Project Lead for the Dojo Toolkit from 2004 to 2008 and is Director of R&D at SitePen, a consultancy focused on the development of web applications, exceptional user experience, and pushing the limits of the web. Currently, he serves as President of the Dojo Foundation, an organization that supports development of several high-quality, open source, JavaScript projects and distributes them under liberal terms. Prior to joining SitePen, Russell was a senior engineer at JotSpot and Informatica where he helped both companies build highly interactive, web interfaces. His earlier, open source involvement included stints as editor of the OWASP Guide to Building Secure Web Applications and primary author of the netWindows DHTML toolkit.

More About Alex »

NFJS, the Magazine

May Issue Now Available
  • Client-Side MVC with Spine.js, Part 1

    by Craig Walls
  • On Prototypal Inheritance, Part 2

    by Raju Gandhi
  • Making use of Scala Lazy Collections

    by Venkat Subramaniam
  • Integration Testing Web Applications Using Gradle

    by Kenneth Kousen
Learn More »