From: Lasse Reichstein Nielsen on
Thomas 'PointedEars' Lahn <PointedEars(a)web.de> writes:

> But that is _not_ the correct way to test it as far too many variables are
> involved. Instead, the correct test is to call it in a /CallExpression/
> with /Arguments/ and see if *that* throws a general TypeError; it does not,
> it returns a value (`null' or an object reference) instead, so by all
> accounts the object created by /x/ in /x/() must implement [[Call]].

That, or the ECMAScript implementation implements an extension that
allows using some objects without [[Call]] in call expressions in some
cases. It's really hard to say what is being extended how ... if it
even makes sense at all.

[[Call]] is a specification level detail. Implementations need not
have any concrete implementation of it. I.e., checking whether a
regexp has a [[Call]] property in an concrete implementation is
meaningless. You can at most check whether it behaves as the
specification says that objects with a [[Call]] property should.

> That Function.prototype.call() throws a TypeError when passed a
> reference to a RegExp instance is nothing more than a peculiarity,
> maybe an oversight, that can be expected of an undocumented language
> feature like this.

All you can test is how it works when used in places where the
specification expectes a [[Call]] property. For Firefox, that seems
to give different results depending on the usage (direct call vs using
Function.prototype.call, and I concur that it's likely to be an
oversight - or a deliberate "if you do that, we can't be bothered").
On other implementations (e.g., Opera) they give the same result.
Both extend the language wrt. the specification. The extensions are
not required to be explainable in terms of the specification.

/L
--
Lasse Reichstein Holst Nielsen
'Javascript frameworks is a disruptive technology'

From: Dr J R Stockton on
In comp.lang.javascript message <5PGdnYpJ6KB9vmfXnZ2dnUVZ_ohi4p2d(a)gigane
ws.com>, Tue, 10 Nov 2009 21:39:28, kangax <kangax(a)gmail.com> posted:

>I have no experience with other languages, but I still find type
>checking useful. I find it easier to read and cleaner overall to have
>`isArray(something)` rather than `typeof something.length == "number"`.
>When I read the latter one in the code, my mind still automatically
>translates it to the former one — "Oh, ok... here we're checking if
>something is array...".

In languages like Algol, Pascal, Delphi, type-checking refers at least
mainly to compile-time activity. The sine routine, for example, can
only be given as argument an integer-type or float-type literal,
variable, or expression (and the calling code will float an integer-
type); it returns a float which can only be assigned to / used as a
float.

Although input arguments can be given as literals, variables, or
expression, output arguments must be variables of the correct type.

Pointers are generally typed; a pointer-to-integer cannot point to a
float. Different types can represent the same sort of thing, for
example an integer of pounds or an integer of euros or an integer of
armadillos.

A variable on one type can be cast into a different type of the same
size, without generating run-tome code. So you can still add pounds to
euros if counting coins, with reduced risk of including any armadillos
you may have about the place.

You might find <a href="http://www.masswerk.at/algol60/report.htm">The
Algol 60 Report</a>, or the Pascal equivalent, interesting.

--
(c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
Proper <= 4-line sig. separator as above, a line exactly "-- " (SonOfRFC1036)
Do not Mail News to me. Before a reply, quote with ">" or "> " (SonOfRFC1036)
From: Richard Cornford on
kangax wrote:
> Richard Cornford wrote:
>> kangax wrote:
>>> Garrett Smith wrote:
>> <snip>
>>>> That's odd. Seems in Tracemonkey, a RegExp is callable without
>>>> implementing [[Call]], or ? A bug in there syntax extension,
>>>> due to internal typechecking for RegExp, as:
>>>> typeof /a/
>>>
>>> Yes, from what I remember, Mozilla makes regex objects callable
>>> without actually giving them [[Call]].
>>
>> That would be very clear violation of ECMA 262, 3rd Ed., where
>> Section 11.2.3 (Function Calls) features the words "If Result(3)
>> does not implement the internal [[Call]] method , throw a
>> TypeError exception" as step 5 in its algorithm. That is, in
>> ES3 terms, if it does not have a [[Call]] method it cannot be
>> called, and so if it can be called it _must_ have a [[Call]]
>> method (or at least that is the required behaviour, so the
>> ability to call something has direct implications for all
>> other situations where the existence of a [[Call]] method is
>> relevant). The specifics have moved around in ES5, but the
>> internal IsCallable function still boils down to 'does the
>> object have a [[Call]] method', so nothing has really changed.
>
> Yes, one way or another Mozilla's implementation comes out to be
> non-conforming.

Given that ECMAScript is allowed to have 'extensions', I have been
wondering if what Mozilla is doing can be put across as an 'extension'
of some sort. Two parts of the (3rd Ed.) spec talk about 'extensions'
(what is, or is not, allowed); Section 16 (Errors) and Section 2
(Conformance),.

Section 2 states that; "A conforming implementation of ECMAScript is
permitted to support program and regular expression syntax not described
in this specification." So is allowing a regular expression to be called
even if it does not have a [[Call]] method a 'syntax extension'? I
don't see how it can be, as the syntax of a function call is unchanged
even when applied to regular expressions (in pure (non-extended)
ECMAScript calling a regular expression is not a syntax error, even if
it can be expected to result in a runtime error if executed). Or at
least, in this form:-

var x = /a/g;
var y = x('a');

- there is no syntax error anD no deviation from the specified syntax.
However:-

var y = /a/g('a');

- is a bit more problematic in ES3. We start at the syntax for Function
Call (11.2.3):-

CallExpression : MemberExpression Arguments

- and then have to examine MemberExpression (11.2)-

MemberExpression :
PrimaryExpression
FunctionExpression
MemberExpression [ Expression ]
MemberExpression . Identifier
new MemberExpression Arguments

- where we are expecting PrimaryExpression to be pertinent, so to
section 11.1:-

PrimaryExpression :
this
Identifier
Literal
ArrayLiteral
ObjectLiteral
( Expression )

In is the inclusion of Identifier in the PrimaryExpression list that
allows the first form of the syntax above, and guarantees that the
language's syntax cannot prevent a call to a regular expression.(at
least if you don't look too hard at the right hand side of the
assignment production and realise that ES3 makes no assertion about a
regular expression literal being an Expression of any sort). We might
expect the RegularExpressionLiteral to be in the list for Literal
(section 7.8):-

Literal ::
NullLiteral
BooleanLiteral
NumericLiteral
StringLiteral

- but it is not. ES5 fixes this by adding RegularExpressionLiteral to
the end of the list for Literal.

In any event, either it is a syntax error to use a
RegularExpressionLiteral at any point in an ES3 Program, or ES3 syntax
allows them to be called (in the sense of allowing them to be the
operand of the 'call operator', that is, it allows you to try to call
them in the same way as it allows you to call an Array or an object) and
so an ability to call them is not a 'syntax extension'.

The "Conformance" section (2) also states that: "A conforming
implementation of ECMAScript must provide and support all the types,
values, objects, properties, functions, and program syntax and semantics
described in this specification.", which means that you cannot change
the meaning of a function call (that would be failing to follow the
semantics of the specification. A (successful) function call means
executing the [[Call]] method of a callable object. Which boils down to;
'If you can call it, it must have a [[Call]] method' (or 'if you can
call it, it must behave as if it has a [[Call]] method').

Section 16 states that "An implementation may provide additional types,
values, objects, properties, and functions beyond those described in
this specification.", and Section 2 says; "A conforming implementation
of ECMAScript is permitted to provide additional types, values, objects,
properties, and functions beyond those described in this specification.
In particular, a conforming implementation of ECMAScript is permitted to
provide properties not described in this specification, and values for
those properties, for objects that are described in this specification."

A provision to provide additional properties may be used to justify a
regular expression having additional properties, such as a [[Call]]
internal property in addition to those laid out in the spec. Thus a
callable regular expression seems to be allowed by the specification.

> If regex objects have [[Call]],

Which I think the spec would allow.

> then `typeof` rules are violated;

There is the one I don't see any way around. Regular expressions are
allowed to be callable _because_ they are allowed to have a [[Call]]
property in addition to those laid out in the spec, but if they do have
a [[Call]] method they should produce 'function' if tested with -
typeof - (and be subject to Function.prototype.call/apply.call/apply -).

> if it doesn't � function call rules are (as you have
> explained). But that's the price of compatibility, and there are
> other examples of spec violations like that (`ToObject` not
> throwing Error in for-in, comes to mind :))

That one is not a price of compatibility because for many years
JavaScript(tm) regular expressions have been callable and have been
reporting themselves as 'function' if tested with - typeof -. Any price
this is extorting is the price of more or less ignorant web developers
insisting that what they believe should be the case become the case,
despite the consequences.

> There's an old-ish Mozilla issue
> https://bugzilla.mozilla.org/show_bug.cgi?id=61911 which,
> as I understand, is the one responsible for making typeof
> regex to be "object", not "function" as they had it before
> (e.g. in FF <= 2).

And you notice that the primarily complaint for the bug is somewhere
between technically inaccurate and plain wrong.

> Looking at their patch, I can't tell if [[Class]] was removed

[[Call]]?

> on regex objects or if they changed some internal `typeof`
> mapping (mapping of object types to return values of `typeof`).
>
> This whole issue was recently mentioned on es-discuss once
> again
> (https://mail.mozilla.org/pipermail/es-discuss/2009-August/009718.html),
> this time in context of `JSON.stringify`. Per specs,
> `JSON.stringify` should treat values that are callable (IsCallable
> returns true) as undefined. This is essentially why Function
> objects are ignored during serialization.
>
> The fun part is WebKit making regex objects callable. This makes
> `JSON.stringify(/x/)` return `undefined` in WebKit, but `{}` in
> Firefox,
> resulting in a nice cross-browser mess. Here's an involved discussion
> on this topic � https://bugs.webkit.org/show_bug.cgi?id=28117.
>
> We can blame specs and the way certain things are underspecified
> there. It's not very clear if RegExp objects can implement [[Call]] as
> part of allowed extension.

I think they can, but I don't think that there is any way to avoid the
consequences without violating something.

>> On e of the main things that has dogged the - isFunction - question
>> over its very long history is that very few people have been willing
>> to state what 'being a function' represents. If you can give a clear
>> definition of what 'being a function' is then you are probably
>> in a position to either design and effective - isFunction - method,
>> or to declare the determination untestable and so give up the
>> attempt.
>> Instead we see lots of example of - isFunction - method that do
>> something, get criticised for the inconsistencies in that something,
>> and then get changed so they do something else, with nobody ever
>> stating what the definition of 'Function' is that their - isFunction
>> - is supposed to be testing.
>
> Right on point.
>
> This is why we should teach people internals (at least some) of the
> language. Understanding difference between native/host objects, and
> what [[Call]] is, would make things much easier for everyone.
>
>>
>> Personally, I like a definition of 'function' that goes; "if you
>> can call it then it is a function". It is a definition that rules
>> out the viability of an - isFunction - test function (you would
>> have to call the object to see if it is callable, and that might
>> have side-effects), but it is also a very simple/obvious definition
>> that does not introduce issues of itself.
>>
>> A (one of the many) bugbears of - isFunction - Firefox's response
>> to:-
>>
>> var x = document.createElement('OBJECT');
>>
>> - which, when tested with - typeof - returns 'function'. This is
>> seen as incorrect, e.g.:-
>>
>> <URL: http://jsninja.com/Functions#Function_Type >
>
> And understanding of host objects and their unspecified nature
> would completely avoid this problem.

But avoid the problem how? Presumably by triggering the realization that
the general task of identifying some sort of 'type' by examining an
arbitrary value is unsolvable, leading to the realization that code
design should not then be predicated on the ability to derive types from
arbitrary values.

That is not going to be a welcome realization for someone who has
already published/distributed/employed an API predicated on the
expectation of being able to do just that.

>> The idea being that - createElement - should return an object
>> implementing the Element (and by implication Node) interfaces
>> from the W3C DOM (which is true), and that those object should
>> not be callable (which is an assertion that has no technical
>> basis[1]), and therefore that the - typeof - operation applied
>> to such an object should not result in 'function'.
>>
>> [1] The W3C DOM is defined in terms of interfaces; sets of
>> properties and methods that object implementing those interfaces
>> must possess (in some practical sense). Neither ECMAScript, the
>> W3C DOM specs nor the ECMAScript bindings for the DOM interfaces
>> place any restrictions on the nature of the objects implementing
>> an interface, and as ECMAScript functions are objects there is
>> absolutely no reason for any object implementing a W3C DOM interface
>> not to be an ECMAScript function. Thus Element and Node
>> interface implementing objects could be functions (as could objects
>> implementing HTMLCollection, NodeList or NamedNodeMap), the decision
>> is left up to the creators of the DOM providing
>> host.
>
> I have always wondered why ECMA bindings don't define property
> attributes (such as those from 8.6.1 and 8.6.2).

When a DOM property is stated as read-only (and that restriction is
implemented) then it is reasonable to assume that ECMAScript -
ReadOnly - attribute does apply. Other characteristics of such object's;
enumerability, general mutability, etc. are not really the
responsibility/concern of the W3C interfaces.

But in any event, remember that the W3C does not employ people with a
good understanding of ECMAScript and/or browser scripting to work on
their APIs, so they are bound to always botch something.

>> If you try to call the Firefox OBJECT element an exception is
>> thrown, but it is not the "x is not a function" exception that
>> would be thrown if the OBJECT element were not callable. The
>> implication being that the element is callable and the exception
>> that is thrown is thrown within the call. So, by a very reasonable
>> definition of 'being a function' the Firefox OBJECT element is a
>> function (it can be called), and so its resulting in 'function'
>> when - typeof - is applied is actually a very reasonable
>> indicator of a truth about the nature of the object in question.
>
> Yes.
>
>> The point being that there is no technical reason to expect to
>> be able to discriminate between objects implementing the Element
>> interface (or any other DOM specified interface) and an ECMAScript
>> function. This immediately brings into question the worth of
>> having an - isFunction - test function in the first place,
>> especially in relation to its common use in attempting to emulate
>> 'method overloading' in ECMAScript. (In fact, it brings into
>> question the general viability of emulating 'method overloading'
>> in javascript, when you can only make superficial discriminations
>> between the types of values that are the arguments
>> to a function call).
>
> I find overloading to be useful when used sparingly.

I find method overloading useful. Not when used sparingly (as my sparing
use of it is a consequence of its very limited viability) but when used
selectively. That is, I am only going to attempt to discriminate between
value types when I know enough about the possible range of values to be
certain that the discrimination test can tell me what I need to know.

> Consider an interface of 2d point implementation, where setting
> and retrieval of x/y properties is performed through corresponding
> methods.
>
> function Point(x,y){
> this.x = x;
> this.y = y;
> }
> Point.prototype.getX = function(){
> return this.x;
> };
> Point.prototype.setX = function(value){
> this.x = value;
> };
>
> // similar getY, setY implementation
>
> var myPoint = new Point(10, 20);
>
> Now consider a case of "moving" a point by a certain value:
>
> myPoint.setX(myPoint.getX() + 10);
>
> This is perfectly fine, of course, but there's a possibility to
> implement something more elegant and cleaner:
>
> myPoint.setX(function(value){
> return value + 10;
> });

There are a couple of subjective judgments in that's being "more elegant
and cleaner", but that is not important here.

> Valid values of `x` can only be numeric ones, so it's safe to use
> overloading here:
>
> Point.prototype.setX = function(value){
> if (typeof value == "number") {
> this.x = value;
> }
> else {
> this.x = value(this.x);
> }
> };

So there is effectively a contract in the API which states that the
values passed into the method may only be numeric primitives or
functions that are passed a numeric argument and return a numeric
result. Which is a completely valid and viable approach to having some
form of 'method overloading' while avoiding the insolvability of the
type identification problem in the general case (and is pretty much
exactly what I would do (internal detail and notion of 'elegance'
aside)).

<snip>
> I understand that there are alternative ways to accomplish this
> (such as introducing another method).

Where introducing another method is perfectly valid as with the
'overloading' you have it is necessary for the programmer to be aware of
the types being passed as arguments at the point of calling the method,
and so knowing the type could then know which method to use with that
type.

>> The relevance for a regular expression's having, or not having,
>> a [[Call] method? If you cannot expect to be able to discriminate
>> a DOM node from a function not finding it easy to discrimination
>> a regular expression from a function (using - typeof - (as the
>> specific discrimination by duck-typing the respective object's
>> methods/properties is viable)) is not making things any worse.
>
> isFunction can be specified to work reliably with native objects
> only, but regexp having [[Call]] would still hardly matter.

Yes, one of the ways of avoiding the general type identification problem
is to constrain the range of possible valid values. It is quite
reasonable, so long as you define the expected behavior/ argument ranges
for - isFunction - in advance.

> It really makes sense to differentiate objects that are callable
> (i.e. native, implement [[Call]], and so should return "function"
> on typeof) and those that are instances of Function (have
> `Function.prototype` in their prototype chain, and so can be
> tested with `instanceof` or `constructor`).

That probably depends a bit on the context. If you can guarantee that
the system will not contain any objects that are not callable but still
inherit from - Function.prototype - then there is no reason for trying
to discriminate between those non-existent objects and any others.

> Oh wait, we also have [[Class]] == "Function" :) If object is native
> and has [[Class]] == "Function", it's definitely callable
> (as per 13.2); however, if it's native and its [[Class]] is not
> "Function" it could be callable or it could be not (as the
> regexp case shows, where implementation gives [[Call]] to object
> with [[Class]] == "RegExp").

Yes, and a definition of 'being a function' that says a 'function' is
only any native function (all host objects/methods and unexpectedly
callable objects are then not what we are calling a 'function') is at
least a workable definition.

>>> In WebKit, on the other hand, regex do have [[Call]] and so
>>> typeof returns "function", as per specs (native object + has
>>> [[Call]] == "function").
>> <snip>
>>>> Many won't read the documentation of others (including pertinent
>>>> specifications, as witnessed recently on this NG). Developers
>>>> often skip right to the "what does it do" (functions, examples,
>>>> or tests).
>>
>> I recall one of my colleagues being amused to find me reading
>> the SOAP/WSDL specifications prior to writing a SOAP client for
>> our web applications.
>
> I noticed that not many people are fond of reading specs.
<snip>

Many people are not fond of paying taxes.

Richard.

From: Garrett Smith on
Richard Cornford wrote:
> kangax wrote:
>> Richard Cornford wrote:
>>> kangax wrote:
>>>> Garrett Smith wrote:
>>> <snip>
>>>>> That's odd. Seems in Tracemonkey, a RegExp is callable without
>>>>> implementing [[Call]], or ? A bug in there syntax extension,
>>>>> due to internal typechecking for RegExp, as:
>>>>> typeof /a/
>>>>
>>>> Yes, from what I remember, Mozilla makes regex objects callable
>>>> without actually giving them [[Call]].
>>>
>>> That would be very clear violation of ECMA 262, 3rd Ed., where
>>> Section 11.2.3 (Function Calls) features the words "If Result(3)
>>> does not implement the internal [[Call]] method , throw a
>>> TypeError exception" as step 5 in its algorithm. That is, in
>>> ES3 terms, if it does not have a [[Call]] method it cannot be
>>> called, and so if it can be called it _must_ have a [[Call]]
>>> method (or at least that is the required behaviour, so the
>>> ability to call something has direct implications for all
>>> other situations where the existence of a [[Call]] method is
>>> relevant). The specifics have moved around in ES5, but the
>>> internal IsCallable function still boils down to 'does the
>>> object have a [[Call]] method', so nothing has really changed.
>>
>> Yes, one way or another Mozilla's implementation comes out to be
>> non-conforming.
>
> Given that ECMAScript is allowed to have 'extensions', I have been
> wondering if what Mozilla is doing can be put across as an 'extension'
> of some sort. Two parts of the (3rd Ed.) spec talk about 'extensions'
> (what is, or is not, allowed); Section 16 (Errors) and Section 2
> (Conformance),.
>

| A conforming implementation of ECMAScript is permitted to provide
| additional types, values, objects, properties

A [[Call]] property would be an additional property. It would also be
against what seems to be an intention of the specification as:

Additional properties. [[Call]] is an internal property. I believe this
is allowed.

The spec hints in a few places about callable built-ins that are not
functions, but doesn't name one.

Take section 15:
| Unless specified otherwise, the [[Class]] property of a built-in
| object is "Function" if that built-in object has a [[Call]] property,
| or "Object" if that built-in object does not have a [[Call]] property.

Which seems to indicate that there is some sort of built-in, callable.
Where?

and:

| The global object does not have a [[Call]] property; it is not
| possible to invoke the global object as a function.

Why even mention that? It would not be expected, and it is not mentioned
for any other object, e.g. "Array instances do not have [[Call]]
property." The only reason I can see for mentioning it is that it is
something they wanted to allow. As if to let an implementation make
something, RegExp, maybe, callable.

> Section 2 states that; "A conforming implementation of ECMAScript is
> permitted to support program and regular expression syntax not described
> in this specification." So is allowing a regular expression to be called
> even if it does not have a [[Call]] method a 'syntax extension'? I
> don't see how it can be, as the syntax of a function call is unchanged
> even when applied to regular expressions (in pure (non-extended)
> ECMAScript calling a regular expression is not a syntax error, even if
> it can be expected to result in a runtime error if executed). Or at
> least, in this form:-
>
> var x = /a/g;
> var y = x('a');
>
> - there is no syntax error anD no deviation from the specified syntax.
> However:-
>
> var y = /a/g('a');
>
> - is a bit more problematic in ES3. We start at the syntax for Function
> Call (11.2.3):-
>
> CallExpression : MemberExpression Arguments
>
> - and then have to examine MemberExpression (11.2)-
>
> MemberExpression :
> PrimaryExpression
> FunctionExpression
> MemberExpression [ Expression ]
> MemberExpression . Identifier
> new MemberExpression Arguments
>
> - where we are expecting PrimaryExpression to be pertinent, so to
> section 11.1:-
>
> PrimaryExpression :
> this
> Identifier
> Literal
> ArrayLiteral
> ObjectLiteral
> ( Expression )
>
> In is the inclusion of Identifier in the PrimaryExpression list that
> allows the first form of the syntax above, and guarantees that the
> language's syntax cannot prevent a call to a regular expression.(at
> least if you don't look too hard at the right hand side of the
> assignment production and realise that ES3 makes no assertion about a
> regular expression literal being an Expression of any sort). We might
> expect the RegularExpressionLiteral to be in the list for Literal
> (section 7.8):-
>
> Literal ::
> NullLiteral
> BooleanLiteral
> NumericLiteral
> StringLiteral
>
> - but it is not. ES5 fixes this by adding RegularExpressionLiteral to
> the end of the list for Literal.
>

I was wondering when someone would mention that.

I asserted earlier that a RegularExpressionLiteral was a
MemberExpression but nobody called me on that.

Likewise with:

/a/.test("a");

- where the RegularExpressionLiteral is handled as a MemberExpression.

> In any event, either it is a syntax error to use a
> RegularExpressionLiteral at any point in an ES3 Program,

It is an understated shortcoming in the specification.

[...]
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
From: kangax on
Richard Cornford wrote:
> kangax wrote:
[...]
>> Yes, one way or another Mozilla's implementation comes out to be
>> non-conforming.
>
> Given that ECMAScript is allowed to have 'extensions', I have been
> wondering if what Mozilla is doing can be put across as an 'extension'
> of some sort. Two parts of the (3rd Ed.) spec talk about 'extensions'
> (what is, or is not, allowed); Section 16 (Errors) and Section 2
> (Conformance),.
>
> Section 2 states that; "A conforming implementation of ECMAScript is
> permitted to support program and regular expression syntax not described
> in this specification." So is allowing a regular expression to be called
> even if it does not have a [[Call]] method a 'syntax extension'? I
> don't see how it can be, as the syntax of a function call is unchanged
> even when applied to regular expressions (in pure (non-extended)
> ECMAScript calling a regular expression is not a syntax error, even if
> it can be expected to result in a runtime error if executed). Or at
> least, in this form:-
>
> var x = /a/g;
> var y = x('a');
>
> - there is no syntax error anD no deviation from the specified syntax.
> However:-
>
> var y = /a/g('a');
>
> - is a bit more problematic in ES3. We start at the syntax for Function
> Call (11.2.3):-
>
> CallExpression : MemberExpression Arguments
>
> - and then have to examine MemberExpression (11.2)-
>
> MemberExpression :
> PrimaryExpression
> FunctionExpression
> MemberExpression [ Expression ]
> MemberExpression . Identifier
> new MemberExpression Arguments
>
> - where we are expecting PrimaryExpression to be pertinent, so to
> section 11.1:-
>
> PrimaryExpression :
> this
> Identifier
> Literal
> ArrayLiteral
> ObjectLiteral
> ( Expression )
>
> In is the inclusion of Identifier in the PrimaryExpression list that
> allows the first form of the syntax above, and guarantees that the
> language's syntax cannot prevent a call to a regular expression.(at
> least if you don't look too hard at the right hand side of the
> assignment production and realise that ES3 makes no assertion about a
> regular expression literal being an Expression of any sort). We might
> expect the RegularExpressionLiteral to be in the list for Literal
> (section 7.8):-
>
> Literal ::
> NullLiteral
> BooleanLiteral
> NumericLiteral
> StringLiteral
>
> - but it is not. ES5 fixes this by adding RegularExpressionLiteral to
> the end of the list for Literal.
>
> In any event, either it is a syntax error to use a
> RegularExpressionLiteral at any point in an ES3 Program, or ES3 syntax
> allows them to be called (in the sense of allowing them to be the
> operand of the 'call operator', that is, it allows you to try to call
> them in the same way as it allows you to call an Array or an object) and
> so an ability to call them is not a 'syntax extension'

Interesting. It hasn't occurred to me to check syntactic conformance of
callable regex literals.

[...]

>> if it doesn't � function call rules are (as you have
>> explained). But that's the price of compatibility, and there are
>> other examples of spec violations like that (`ToObject` not
>> throwing Error in for-in, comes to mind :))
>
> That one is not a price of compatibility because for many years
> JavaScript(tm) regular expressions have been callable and have been
> reporting themselves as 'function' if tested with - typeof -. Any price
> this is extorting is the price of more or less ignorant web developers
> insisting that what they believe should be the case become the case,
> despite the consequences.

I don't know the whole story there, but I was basing my assumptions on
Brendan's comments to this whole "situation". To cite one
(https://bugs.webkit.org/show_bug.cgi?id=28117#c21)

"[...]
We fixed the higher-numbered one first, making typeof /a/ == "function".
But then we retreated in 61911 due to complaints and (I seem to recall;
it's hard to find evidence at the moment) real web compatibility problems.

The complaints weren't all from spec-purists who did not like the
extension in SpiderMonkey that allows /a/(s) as shorthand for
/a/.exec(s). I remember more than a few places where real code was
flummoxed by typeof /a/ == "function". This confusing result broke code,
whether or not such code expected (this would have been Mozilla-specific
code, originally) to be able to call a regexp as shorthand for exec'ing it.

Anyway, we threw in the towel with the resolution of 61911. The only
further retreat for us is to remove callability, but that may be hard.
We may be stuck. We can't easily go back to typeof /a/ == "function", in
any event.

/be"

Is it only complains of incompetent web developers that triggered this
change? I don't know. It certainly looks like there could be more to it
(e.g. incompetent legacy scripts, which should still be supported ;))

[...]

>> Looking at their patch, I can't tell if [[Class]] was removed
>
> [[Call]]?

Yep.

[...]

>>> Personally, I like a definition of 'function' that goes; "if you
>>> can call it then it is a function". It is a definition that rules
>>> out the viability of an - isFunction - test function (you would
>>> have to call the object to see if it is callable, and that might
>>> have side-effects), but it is also a very simple/obvious definition
>>> that does not introduce issues of itself.
>>>
>>> A (one of the many) bugbears of - isFunction - Firefox's response
>>> to:-
>>>
>>> var x = document.createElement('OBJECT');
>>>
>>> - which, when tested with - typeof - returns 'function'. This is
>>> seen as incorrect, e.g.:-
>>>
>>> <URL: http://jsninja.com/Functions#Function_Type >
>>
>> And understanding of host objects and their unspecified nature
>> would completely avoid this problem.
>
> But avoid the problem how? Presumably by triggering the realization that
> the general task of identifying some sort of 'type' by examining an
> arbitrary value is unsolvable, leading to the realization that code
> design should not then be predicated on the ability to derive types from
> arbitrary values.

Understanding the nature of host objects would avoid never ending
patching of type-checking utility to account for cases that can
inherently take any form.

>
> That is not going to be a welcome realization for someone who has
> already published/distributed/employed an API predicated on the
> expectation of being able to do just that.
>
>>> The idea being that - createElement - should return an object
>>> implementing the Element (and by implication Node) interfaces
>>> from the W3C DOM (which is true), and that those object should
>>> not be callable (which is an assertion that has no technical
>>> basis[1]), and therefore that the - typeof - operation applied
>>> to such an object should not result in 'function'.
>>>
>>> [1] The W3C DOM is defined in terms of interfaces; sets of
>>> properties and methods that object implementing those interfaces
>>> must possess (in some practical sense). Neither ECMAScript, the
>>> W3C DOM specs nor the ECMAScript bindings for the DOM interfaces
>>> place any restrictions on the nature of the objects implementing
>>> an interface, and as ECMAScript functions are objects there is
>>> absolutely no reason for any object implementing a W3C DOM interface
>>> not to be an ECMAScript function. Thus Element and Node
>>> interface implementing objects could be functions (as could objects
>>> implementing HTMLCollection, NodeList or NamedNodeMap), the decision
>>> is left up to the creators of the DOM providing
>>> host.
>>
>> I have always wondered why ECMA bindings don't define property
>> attributes (such as those from 8.6.1 and 8.6.2).
>
> When a DOM property is stated as read-only (and that restriction is
> implemented) then it is reasonable to assume that ECMAScript -
> ReadOnly - attribute does apply. Other characteristics of such object's;
> enumerability, general mutability, etc. are not really the
> responsibility/concern of the W3C interfaces.

Yes, it appears to be so.

>
> But in any event, remember that the W3C does not employ people with a
> good understanding of ECMAScript and/or browser scripting to work on
> their APIs, so they are bound to always botch something.

Ok :)

[...]

> <snip>
>> I understand that there are alternative ways to accomplish this
>> (such as introducing another method).
>
> Where introducing another method is perfectly valid as with the
> 'overloading' you have it is necessary for the programmer to be aware of
> the types being passed as arguments at the point of calling the method,
> and so knowing the type could then know which method to use with that
> type.

And I'm not sure which one makes for a more convenient/intuitive API
design. It seems that adding another method in situation like this could
actually result in a more understandable code; method name could hint at
method's semantics, whereas overloading could lead to ambiguity.

[...]

>> Oh wait, we also have [[Class]] == "Function" :) If object is native
>> and has [[Class]] == "Function", it's definitely callable
>> (as per 13.2); however, if it's native and its [[Class]] is not
>> "Function" it could be callable or it could be not (as the
>> regexp case shows, where implementation gives [[Call]] to object
>> with [[Class]] == "RegExp").
>
> Yes, and a definition of 'being a function' that says a 'function' is
> only any native function (all host objects/methods and unexpectedly
> callable objects are then not what we are calling a 'function') is at
> least a workable definition.

Which is why testing object for [[Class]] == "Function" is a
more-or-less "viable" solution for isFunction utility, as long as
isFunction defines function to be a Function object.

This is practically an alternative to instanceof check, but the one
that's cross-frame -safe. Instead of asserting that something is a
Function object by checking if `Function.prototype` is in its prototype
chain, we check if its [[Class]] has a "Function" value.

There are, of course, other implications here that make this
"alternative" so much different that instanceof check � possibility of
host objects implementing [[Class]] == "Function" (and so resulting in
false positives) or IE's wrapping of cross-window objects (and so giving
false positives once again).

In any case, the more important question to ask here is what exactly it
is that needs to be done with an object which requires to know whether
it is a function. When this question is asked, the solution usually
becomes much more apparent and viable.

[...]

--
kangax