callable objects ?

Brendan Eich brendan at
Sat Apr 14 19:45:33 PDT 2012

Irakli Gozalishvili wrote:
> It would be amazing to have clojure like protocols in JS  even without 
> `IFn`. I think it's very good feet and very useful in JS where each 
> library has it's own flavored API. I wrote more about it here: 

Still hoping Mark will weigh in.

> Also why would callable objects return `function` on `typeof(callable)`.
I didn't say that was a good idea, I only noted that we're breaking an 
invariant for "native objects". Not unthinkable!

> As a matter of fact I think it should be `object` and something new 
> like `Object.isCallable(object)`

See callable(x) below. Putting it on Object and using isCallable 
Java-style naming seems safer but makes me sad -- so verbose!


> may be used to check for call-ability. This way old code either will 
> reject non functions or will shim `Object.isCallable` to support new 
> constructs.
> Regards
> --
> Irakli Gozalishvili
> Web:
> On Wednesday, 2012-04-11 at 11:54 , Brendan Eich wrote:
>> Michael Fogus wrote:
>>> I know some things about ClojureScript and would be happy to answer
>>> any direct questions. However, I think its notion (and Clojure proper)
>>> is that "functions are data are functions" is very powerful.
>> It's a great idea (I first met John McCarthy in 1977 when I was 16). Too
>> bad JS was not allowed to be "Scheme in the browser".
>>> A lot of
>>> interesting patterns fall out of this as others have pointed out.
>> I'm ready to jump in with both feet, except for JS's age and the
>> possibility that too much code on the web counts on things like
>> (typeof x == "function") <=> x() works and x.apply is the expected 
>> built-in
>> No problem, you say, we can leave typeof alone and add a callable
>> predicate and evangelize that. Ok, provided the callable protocol uses
>> an ES6 private name (think gensym), any public name could be in use and
>> make a false positive when testing callability.
>> So let's use a well-known private (unique, should say) name, e.g.
>> module std {
>> ...
>> export const invokeName = Name.create("invoke");
>> export function callable(v) {
>> if (typeof v == "function")
>> return true;
>> if (typeof v == "object" && v != null)
>> return invokeName in v; // could be pickier but let's start here
>> return false;
>> }
>> }
>> // make an object obj be callable:
>> obj[invokeName] = function (...args) { /* ... */ };
>> Looks ok, ignoring details such as how the client code gets the standard
>> unique name binding (import invokeName from "@std" or some such).
>> One can't assume apply or call or other Function.prototype heritage is
>> in x just because callable(x) returns true. Callability is wider and
>> weaker than typeof-result "function".
>> IIRC, security conscious folks do not want an attacker to be able to
>> make any old object callable. Cc'ing Mark for his thoughts.
>> /be
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at <mailto:es-discuss at>
> _______________________________________________
> es-discuss mailing list
> es-discuss at

More information about the es-discuss mailing list