callable objects ?

Irakli Gozalishvili rfobic at gmail.com
Tue Apr 10 07:52:12 PDT 2012


BTW In that case you might also want to check out another thread I've started about clojure like protocol base polymorphism:  
https://mail.mozilla.org/pipermail/es-discuss/2012-March/021603.html

As that's exactly what's being used in the gist you've pointed out.  In clojure(script) not only regexps can be made callable, but  many built-in data types already are:

(var map { :foo 1, :bar 2 })
(map :foo) => 1
(:bar map) => 2

Regards
--
Irakli Gozalishvili
Web: http://www.jeditoolkit.com/


On Monday, 2012-04-09 at 16:21 , Brendan Eich wrote:

> This gist about ClojureScript
>  
> https://gist.github.com/2346460
>  
> reminded me of this thread. I need to spend more time learning  
> ClojureScript; maybe someone who knows it has a thought.
>  
> /be
>  
> Irakli Gozalishvili wrote:
> > I have prototyped desugared version of callable objects here:
> >  
> > https://gist.github.com/2312621
> >  
> > I could not use short object syntax and unnamed method as proposed in  
> > original post, so I used regular object syntax and `new` as method  
> > name for unnamed `method`. I tried to illustrates that callable  
> > objects may be more elegant alternative to classes specially in  
> > combination with `<|` (which I expressed as `extend` function).
> >  
> > Regards
> > --
> > Irakli Gozalishvili
> > Web: http://www.jeditoolkit.com/
> >  
> > On Wednesday, 2012-04-04 at 24:56 , David Bruant wrote:
> >  
> > > Le 04/04/2012 02:41, Irakli Gozalishvili a écrit :
> > > >  
> > > > On Tuesday, 2012-04-03 at 14:07 , David Bruant wrote:
> > > >  
> > > > > Le 03/04/2012 22:00, Irakli Gozalishvili a écrit :
> > > > > > Here is more or less what I have in mind:  
> > > > > > https://gist.github.com/2295048
> > > > > >  
> > > > > > // class
> > > > > > var Point = {
> > > > > > (x, y) {
> > > > > > this.getX = { () { return x; } }
> > > > > > this.getY = { () { return x; } }
> > > > > > }
> > > > > > toString() {
> > > > > > return '<' + this.getX() + ',' + this.getY() + '>';
> > > > > > }
> > > > > > }
> > > > > >  
> > > > >  
> > > > > Interesting new function syntax.
> > > > > The prototype and function body could even be declared together.  
> > > > > What about 'length'?
> > > > >  
> > > > > > Also such callable objects provide shorter alternative to current  
> > > > > > function syntax:
> > > > > > // shorter than function
> > > > > > numbers.
> > > > > > filter({ (x) { return x % 2 } }).
> > > > > > // maybe single expression can be even shorter like arrow functions ?
> > > > > > map({ (x) x * x }).
> > > > > > forEach({ (x) { this.add(x) } }, that);
> > > > > >  
> > > > >  
> > > > > +1
> > > > >  
> > > > > > Also this would allow interesting APIs similar to those found in  
> > > > > > clojure:
> > > > > >  
> > > > > > // maps / sets similar like in clojure ?
> > > > > > var map = WeakMap(), key = {}, value = {};
> > > > > > map.set(key, value);
> > > > > > map(key) // => value
> > > > > >  
> > > > >  
> > > > > So far so good.
> > > > >  
> > > > > > key(map) // => value
> > > > > This cannot work for backward-compat reasons. In ES1-5, "key = {}"  
> > > > > creates a regular (non-callable) object.
> > > > >  
> > > >  
> > > >  
> > > >  
> > > > Well I did not suggested it should be backwards compatible, also nor  
> > > > classes nor shorter object syntax is backwards compatible.
> > > >  
> > >  
> > > They are to the extent that they throw an error for being invalid  
> > > syntax in previous version. This is the case for your proposal and  
> > > that's a good thing since that's the back door to introducing new  
> > > features.
> > > However, proposals should be backward compatible in semantics.
> > >  
> > > In your case:
> > >  
> > > var map = WeakMap(), key = {}, value = {};
> > > map.set(key, value);
> > > map(key) // => value
> > > key(map) // => value
> > >  
> > > since key is callable, you have (typeof key === 'function') while ES5  
> > > requires (typeof key === 'object') for objects that are constructed  
> > > with '{}'. There is code out there that relies on typeof for argument  
> > > shifting: 'if the first argument is a function, use that as callback,  
> > > otherwise, use the second argument (first argument being an option  
> > > non-callable object)'. There is this pattern all over the place in  
> > > the mongodb node client as in  
> > > https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L85
> > > In other cases, to pass a handler, some API check if the argument if  
> > > an object and in that case use the 'handle' property or use the  
> > > function is what has been passed is callable.
> > > So, preserving typeof invariants regarding 'object'/'function' is  
> > > crucial to backward compatibility.
> > >  
> > > Likewise for arrays. In ES1-5, (typeof [] === 'object') and the  
> > > suggested semantics of your proposal would break that.
> > >  
> > > As far as I'm concerned, just the object-literal version of function  
> > > is a brilliant idea, no need for the additional semantics.
> > >  
> > > David
> >  
> > _______________________________________________
> > es-discuss mailing list
> > es-discuss at mozilla.org (mailto:es-discuss at mozilla.org)
> > https://mail.mozilla.org/listinfo/es-discuss
> >  
>  
>  
>  


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20120410/7d34f4fa/attachment.html>


More information about the es-discuss mailing list