Type Checking?

Brendan Eich brendan at mozilla.org
Thu Oct 11 16:54:21 PDT 2007

On Oct 11, 2007, at 1:36 PM, Garrett Smith wrote:

> On 10/10/07, Brendan Eich <brendan at mozilla.org> wrote:
>> On Oct 10, 2007, at 3:53 PM, Garrett Smith wrote:
>>    if (it is Callable) ...
> I wonder how host objects will deal with this.
> Will there be a transitive relationship of callable and ()?

For transitivity you need a binary relation. The |is| operator is  
binary and transitive. The () operator is not binary and not in any  
general sense transitive. So I'm not sure what you mean here, but  
moving on:

> If an object accepts arguments, it is callable, and if it is callable,
> it supports ,call(), right?

You mean if (it is Callable) then it.call(thisp, arg1, ..., argN)  
works? No, because (it is Callable) is true for cases where !(it  
instanceof Function). If you want to apply or call a non-function  
callable, use Function.apply(callable, thisp, argArray) or  
Function.call(callable, thisp, arg1, ...argN).

> typeof appendChild; // "object"
> appendChild is Callable; // ???

See the ticket I cited, http://bugs.ecmascript.org/ticket/153, where  
the Callabe structural type is defined as { meta::invoke: * } (or  
possibly { meta::invoke: Function }). That is, if any object  
implements the meta-object hook for invocation, it is callable. As  
shaver notes and ES1-3 put it, this is the [[Call]] meta-method. It  
is exposed in ES4 as meta::invoke. If some future rev of IE (not  
retrofitted with ScreamingMonkey :-/) has a callable DOM method  
appendChild, but (appendChild is Callable) evaluates to false, well,  
that would be a bug.

> In IE, appendChild.call is undefined, yet accepts arguments. It's like
> a host function that's bound, internally, to its node. Its thisArg is
> always the node; execution context is irrelevant. It's an odd duck.

That's not something ES4 will prescribe, but again: use the new-in- 
ES4 static generic Function.call (or Function.apply) if you need to.

> document.all(), document.links(0) are also non-functional, but "do
> something" when you use arguments ().  That something is not [[call]].
> Opera mimicked this odd behavior with document.all and Mozilla did too
> in BackCompat mode.

I don't know what "BackCompat mode" means, but we do reflect  
document.all if a script uses it without object-detecting it, and  
only in such cases (since many well-written scripts fork based on if  
(document.all) ... else ... tests and we want to run the else clause).

This is all not normatively specified by ES4. It's fodder for a  
future WHAT-WG or W3C webapi spec on ES4 DOM binding. But we are  
providing the tools for generalizing callability apart from (it  
instanceof Function), and we are providing static-generic Function. 
{apply,call}. These should be enough.

> Hosts that create such objects create a deceptive and confusing
> interface. It's like "what the heck is this thing?"

I agree, and Gecko's DOM takes pains to reflect methods as instances  
of Function, as far as I know.

I believe this came up on a w3c list in the last year, possibly  
webapi or html-wg. Can someone find the thread?


More information about the Es4-discuss mailing list