Understanding Generic Functions
John Resig
jresig at mozilla.com
Wed Nov 14 17:26:37 PST 2007
Hey All -
So I've been trying to understand generic functions (and their presumed use for Multimethods). Reading through the white paper and the wiki I can surmise the following (and since the RI doesn't include them yet, these are just assumptions):
Generic functions are used like this:
generic function a(b);
generic function a(b:int){}
generic function a(b:string){}
Generics offer a point upon which future functions can be bound, like for operator overloading:
class Foo!{}
generic intrinsic function +(a:string, b:Foo){}
generic intrinsic function +(a:Foo, b:string){}
generic intrinsic function +(a:Foo, b:Foo){}
So that's all well-and-good. Now, where I making an assumption is that it's not possible to do the following:
generic function a(b);
generic function a(b:int){}
generic function a(b:string){}
generic function a(b,c);
generic function a(b:string, c:int){}
also, it's not clear if you can use generics for constructors - so I'm assuming that that's also not possible:
class Foo {
generic function Foo(b);
generic function Foo(b:int){}
generic function Foo(b:string){}
}
Ok - with all of that assumed, I am seriously struggling to think of a real-world use case for generics beyond the compelling operator overloading example.
Assuming that I wanted to continue to try to do method overloading, it sounds like the de-facto solution is to just use the rest arguments to figure out what I want. This is not an acceptable solution. I lose virtually all of the benefits that I had of doing type annotations in the first place if I can't actually use them on "overloaded" functions.
For example, I've been pouring through my JavaScript library (jQuery) looking for ways in which ES4 could be of benefit. I immediately looked to using (what I thought was) method overloading to ease some of the severe complexity of the library. We do overloading on virtually every single method: Thus, if there was no form of method overloading included in ES4, then jQuery would receive significantly less, tangible, benefit from these updates.
To give a couple, crude, examples:
function attr(name : string) : string {
// get attribute value
}
function attr(name : string, value : (string,int)) : jQuery {
// set an attribute value, return a jQuery object
}
function removeEvent() : jQuery {
// Remove all events
for each ( var type in types )
removeEvent( type );
}
function removeEvent(type : string) : jQuery {
// Remove all events of a specific type
for each ( var fn in events[type] )
removeEvent( type, fn );
}
function removeEvent(type : string, fn: Callable) : jQuery {
// Remove the event handler bound to a type
}
Additionally, I've been working on building a DOM implementation to sit on top of the ES4 RI, but have hit some walls, especially with constructors. Thankfully, private/protected/etc. constructors will be implemented at some point (I'm looking forward to it) but I was kind of expecting the ability to do multiple constructors - and even the ability to mix private/protected/public constructors, for example:
class Foo {
private function Foo(){
// Do initialization stuff
}
function Foo(name : string) {
this();
this.name = name;
}
}
I'm simply most concerned about getting a useful version of method overloading and constructor overloading. I'd love to find out that I could use generics to achieve this, but I just don't have a way of determining that right now.
--John
More information about the Es4-discuss
mailing list