On Wed, Mar 7, 2012 at 2:58 AM, David Bruant <[email protected]> wrote:
> Le 07/03/2012 02:10, Brandon Benvie a écrit : > > I start this coming from the standpoint of an honest question that I > > don't know the answer to: is there a specific reason that objects > > can't be callable in js? Aside from the "that's just how the language > > is" answer, I was wondering if there's some other computer sciency or > > performance reason for the restriction. > One further detailled explanation of "that's just how the language work" > would be that a JavaScript invariant is that a value has a stable result > to "typeof". So it's impossible to change a non-callable object into a > callable object without breaking this invariant (as stated by ES5, a > callable object has "function" for it's typeof value while non-callable > objects have "object"). > Scala has a notion of "extractor" objects: http://www.scala-lang.org/node/112 – with the right method signatures, they can be used like a function, or be used in pattern matching (or for us, destructuring only - for now). I can see how this would be useful, and could be achieved using private names instead of method signatures. The result would be an object that could still be typeof "object" and also callable. import {apply,unapply} from "@extractor"; const Twice = { [apply]:function(x){ return x * 2; }, [unapply]:function(z){ return z%2 == 0? z/2 : null; } } let x = Twice(21); // x == 42 let Twice(n) = x; // n == 21 I think the unapply half could be useful in destructuring, though I think it would be distinctly more useful in pattern matching (which I would love to see included). Or the unapply half could just be dropped if too problematic. > > Besides this, I don't see a restriction on why you couldn't just use > functions each time you need an object. > > The biggest restriction would probably just be forcing the way you have to create it. It has to start life as a function and get modified from there. - Russ > > > > I've had this question a number of times but the most recent spart was > > seeing this from Allen Wirfs-Brock: > > > >> //define a non constructible superclass that provides some > Smalltalk-like conventions > >> const AbstractClass = Function.prototype <| { > >> subclassResponsibility() {throw new Error(this.name+" did not > implemented an abstract method")}, > >> shouldNotImplement() {throw new Error(this.name+" should not > implemented by "+this.name)}, > >> name: "AbstractClass", > >> prototype: Object.prototype <|{ > >> get class() {return this.constructor}, > >> error(message) {throw new Error(message)}, > >> subclassResponsibility() {return > this.class.subclassResponsibility()}, > >> shouldNotImplement() {return this.class.shouldNotImplement()}, > >> errorSubscriptBounds(index) {this.error("subscript is out of > bounds: "+index)} > >> } > >> }; > > As it is currently, the behavior of a function is that it defaults to > > be a `constructor-like`. It has a prototype that it bestows upon > > objects JS tells it to create, and it's not even possible for it to > > have no prototype property. I would imagine a callable object is more > > like a non-constructor function (something like isNaN) or, currently, > > it's essentially the same as doing `object.valueOf()`. In fact there's > > nothing stopping one from making every single object they use (aside > > from an array) callable simply by starting with a function literal and > > assigning its __proto__. > However, you do not need to use functions as constructors. > I wish block lambda [1] to be adopted for ES6. I think they would fit > your vision of functions, because it certainly wouldn't make sense to > construct with them and they would certainly have no use of a > 'prototype' property. > > Hopefully, it will be possible to combine block-lambda with the <| > operator to create callable objects with arbitrary prototype. > > > (...) > > Partilly this is resolved with ES6, as is the arraylikes problem. > Indeed. All the "change the prototype at object creation time" was the > rational behind the <| operator (and as you note, it will work for > arrays, and functions and most things) > > David > > [1] http://wiki.ecmascript.org/doku.php?id=strawman:block_lambda_revival > _______________________________________________ > es-discuss mailing list > [email protected] > https://mail.mozilla.org/listinfo/es-discuss >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

