Re: Type Checking?
On 10/10/07, Brendan Eich <[EMAIL PROTECTED]> wrote: > On Oct 10, 2007, at 3:53 PM, Garrett Smith wrote: > > > Typechecking is a problem. > > > > typeof is limited and allows host objects to return anything. The > > problem is that some host objects return "function", for example, a > > NodeList in Safari. This is perfectly legal, according to the spec. > > See http://bugs.ecmascript.org/ticket/153 -- for a general, universal > is-it-callable test, you would write > >if (it is Callable) ... > > > How is type checking addressed in ES4? > > The |is| operator tests universal or Platonic type, which involves > shared, immutable type descriptors that do not vary across windows or > frames. So > >if (a is Array) ... > > will work no matter where a was constructed. > Immutable type descriptor. I like it! > /be > > -- Programming is a collaborative art. ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: Type Checking?
On Oct 10, 2007, at 3:53 PM, Garrett Smith wrote: > Typechecking is a problem. > > typeof is limited and allows host objects to return anything. The > problem is that some host objects return "function", for example, a > NodeList in Safari. This is perfectly legal, according to the spec. See http://bugs.ecmascript.org/ticket/153 -- for a general, universal is-it-callable test, you would write if (it is Callable) ... > How is type checking addressed in ES4? The |is| operator tests universal or Platonic type, which involves shared, immutable type descriptors that do not vary across windows or frames. So if (a is Array) ... will work no matter where a was constructed. /be ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: Type Checking?
On 10/10/07, Brendan Eich <[EMAIL PROTECTED]> wrote: > On Oct 10, 2007, at 3:53 PM, Garrett Smith wrote: > >if (it is Callable) ... > > > The |is| operator tests universal or Platonic type, which involves > shared, immutable type descriptors that do not vary across windows or > frames. So > >if (a is Array) ... > > will work no matter where a was constructed. > I wonder how host objects will deal with this. Will there be a transitive relationship of callable and ()? If an object accepts arguments, it is callable, and if it is callable, it supports ,call(), right? typeof appendChild; // "object" appendChild is Callable; // ??? 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. 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. Hosts that create such objects create a deceptive and confusing interface. It's like "what the heck is this thing?" Garrett > /be > > -- Programming is a collaborative art. ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: Type Checking?
On 10/11/07, Garrett Smith <[EMAIL PROTECTED]> wrote: > If an object accepts arguments, it is callable, and if it is callable, > it supports ,call(), right? Assuming you mean "has itself a Callable member named 'call'", then I think the answer is no -- being Callable means having a [[Call]] operation defined on it, but that operation need not be reflected as a method on the function. You'll be able to use function-call syntax on it, though, which is what typically invokes the [[Call]] operation. Mike (long-time listener, first-time caller) ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: Type Checking?
On Oct 11, 2007, at 1:36 PM, Garrett Smith wrote: > On 10/10/07, Brendan Eich <[EMAIL PROTECTED]> 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? /be ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: Type Checking?
On 10/11/07, Brendan Eich <[EMAIL PROTECTED]> wrote: > On Oct 11, 2007, at 1:36 PM, Garrett Smith wrote: > > > On 10/10/07, Brendan Eich <[EMAIL PROTECTED]> 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). > So these are equivalent? aNonFunctionCallableObj() Function.call( aNonFunctionCallableObj ) > > 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. > If an object is invokable with arguments (), but not a Callable, it's impossible to type check. IE's call-like operation on with () is not [[call]]. Microsoft often says that it is necessary to retain backwards compatibility. I would hope they would Mozilla has this weird function-like thing, too, (only with document.all, which is not used much anymore) > > 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). > document.compatMode "CSS1Compat" -- standards mode "BackCompat" - quirks mode BackCompat supports document.all > 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. > Mozilla really made document.all look like IE's weird collection-that-can-be-invoked-with-(). document.all.call(document, 0) * Non-standard document.all property was used. Use W3C standard document.getElementById() instead. * [Break on this error] undefined javascript: with ... (line 1) document.all.call is not a function Yikes! > I believe this came up on a w3c list in the last year, possibly > webapi or html-wg. Can someone find the thread? > I'll look for that. Garrett > /be > > -- Programming is a collaborative art. ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: Type Checking?
Incomplete sentence > Microsoft often says that it is necessary to retain backwards > compatibility. I would hope they would [not continue on this path.] <-- EDIT. > ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: Type Checking?
On Oct 11, 2007, at 8:02 PM, Garrett Smith wrote: >> If you want to apply or call a non-function >> callable, use Function.apply(callable, thisp, argArray) or >> Function.call(callable, thisp, arg1, ...argN). >> > So these are equivalent? > > aNonFunctionCallableObj() > Function.call( aNonFunctionCallableObj ) We don't need to go back and forth -- I wrote essentially the same thing, but included the optional arguments. The two expressions you wrote are equivalent assuming the global object should bind to |this| for both to be equivalent. > If an object is invokable with arguments (), but not a Callable, it's > impossible to type check. IE's call-like operation on with () is not > [[call]]. Why do you say that? There's no reflection of [[Call]] into the language yet, so how can you tell? (Don't rely on typeof x == "function" meaning x.[[Call]] exists -- browsers do not follow ES3 here, although we tried in SpiderMonkey for years before throwing in the towel.) > Microsoft often says that it is necessary to retain backwards > compatibility. I would hope they would You're barking up the wrong tree here. This is es4-discuss. > Mozilla has this weird function-like thing, too, (only with > document.all, which is not used much anymore) As I keep saying, any reflection of document.all in an ES4 "DOM level 0 plus IE quirks" binding should indeed make (document.all is Callable) => true. >> 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). >> > document.compatMode > "CSS1Compat" -- standards mode > "BackCompat" - quirks mode > > BackCompat supports document.all No, you're mixing things up. As I wrote, our document.all emulation has nothing to do with DOM specs or document.compatMode, and it works irrespective of the latter's value. > Mozilla really made document.all look like IE's weird > collection-that-can-be-invoked-with-(). Like, yeah -- that was the point! /be ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: Type Checking?
On 10/11/07, Brendan Eich <[EMAIL PROTECTED]> wrote: > On Oct 11, 2007, at 8:02 PM, Garrett Smith wrote: > > >> If you want to apply or call a non-function > >> callable, use Function.apply(callable, thisp, argArray) or > >> Function.call(callable, thisp, arg1, ...argN). > >> > > So these are equivalent? > > > > aNonFunctionCallableObj() > > Function.call( aNonFunctionCallableObj ) > > We don't need to go back and forth -- I wrote essentially the same > thing, but included the optional arguments. The two expressions you > wrote are equivalent assuming the global object should bind to |this| > for both to be equivalent. > > > If an object is invokable with arguments (), but not a Callable, it's > > impossible to type check. IE's call-like operation on with () is not > > [[call]]. > > Why do you say that? There's no reflection of [[Call]] into the > language yet, so how can you tell? > Well yeah, you're right, I don't know, it's just a lame guess. Some evidence: * The caller does not provide a reference to the object it acts on. * The typeof operator. typeof appendChild == "object"; // true. I don't know what it is. > (Don't rely on typeof x == "function" meaning x.[[Call]] exists -- > browsers do not follow ES3 here, although we tried in SpiderMonkey > for years before throwing in the towel.) > > > Microsoft often says that it is necessary to retain backwards > > compatibility. I would hope they would > > You're barking up the wrong tree here. This is es4-discuss. > Ok. I meant to say "hope they would not continue with this" (or something like that). Host objects that can act like functions but not be functions are confusing. So that that's out of scope for ES4; it's OK for host objects to have custom behavior. > > Mozilla has this weird function-like thing, too, (only with > > document.all, which is not used much anymore) > > As I keep saying, any reflection of document.all in an ES4 "DOM level > 0 plus IE quirks" binding should indeed make (document.all is > Callable) => true. > > >> 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). > >> > > document.compatMode > > "CSS1Compat" -- standards mode > > "BackCompat" - quirks mode > > > > BackCompat supports document.all > > No, you're mixing things up. As I wrote, our document.all emulation > has nothing to do with DOM specs or document.compatMode, and it works > irrespective of the latter's value. > quirksmode -- document.all works strict mode -- no document.all It is detectable. "all" in document > > Mozilla really made document.all look like IE's weird > > collection-that-can-be-invoked-with-(). > > Like, yeah -- that was the point! Was heavily debated and implemented. Water under the bridge, right? Garrett > > /be > -- Programming is a collaborative art. ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: Type Checking?
On Oct 11, 2007, at 10:36 PM, Garrett Smith wrote: > So that that's out of scope for ES4; it's OK for host objects to have > custom behavior. I'm afraid so, but we could say that host objects that are callable SHOULD be functions if they appear to be functions otherwise; we could say that all callable host objects MUST be compatible with the Callable structural type. > quirksmode -- document.all works > strict mode -- no document.all > > It is detectable. Sorry, you are right -- I didn't grok the document.compatMode reference, but yeah: based on DOCTYPE we either will resolve undetected document.all, or not. >>> Mozilla really made document.all look like IE's weird >>> collection-that-can-be-invoked-with-(). >> >> Like, yeah -- that was the point! > Was heavily debated and implemented. Water under the bridge, right? Way under. See https://bugzilla.mozilla.org/show_bug.cgi?id=248549#c85 /be ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss