On Wed, Mar 7, 2012 at 8:53 AM, Russell Leggett <[email protected]>wrote:
> 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. > <3 Of course, we'd need a completely different pattern for duck-testing callables. If functions were re-specified to include the `apply` private name then testing for its presence may be enough. This would fall down in the face of naive iframe-sandboxing -- is this a big problem? If so, at worst sandboxes could use a proxy to alias the various apply brands (I suspect there's a lighter weight strategy that could work too -- I only say this to note the benefits of using brands for psuedo-typing). > >> 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 > >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

