callable objects ?

Irakli Gozalishvili rfobic at gmail.com
Tue Apr 3 13:00:49 PDT 2012


Hi, 

Please excuse me if this will sound too crazy, but this idea have being growing in my head for so long that I can't stop myself from proposing it here. I have experimented many different ways of doing inheritance in JS:

1. Starting with a simple sugar that reduces machinery involved, similar to backbone.js
https://github.com/Gozala/extendables

2. Finishing with class free prototypal inheritance
https://github.com/Gozala/selfish

I have to say that experience with selfish turned out very interesting, it made things so much simpler no special forms, no twisted relations between constructors and objects, just a plain objects. Most of these things are not obvious until you start using them, but the fact that exemplars (classes) are no different from regular objects in the system makes things much simpler. 

That being said I have also came to realize that in most of the cases functions as exemplars would be a better feet than objects. As a matter of fact if objects could be made callable I think it could could have replaced most of the things that classes are targeting in more elegant way. 

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() + '>';
  }
}

var a = new Point(0, 0)
var b = new Point(1, 7)

// Examples from class proposal

// extend is like create with a diff that second arg is an object.
var SkinnedMesh = Object.extend(THREE.Mesh, {
  (geometry, materials) {
    // call the superclass constructor
    THREE.Mesh.call(this, geometry, materials);
    
    // initialize instance properties
    this.identityMatrix = new THREE.Matrix4();
    this.bones = [];
    this.boneMatrices = [];

    // ...
  }

  update (camera) {
    THREE.Mesh.update.call(this);
  }
});

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);


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
key(map) // => value


And maybe built-ins could have it for doing `[]` work:


// Maybe even non-magical replacement for `[]`

[ 'a', 'b', 'c' ](1) // => 'b'
({ a: 1, b: 2 })('a') // => 1
('b')({ a: 1, b: 2 }) // => 2




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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20120403/0b5e609a/attachment.html>


More information about the es-discuss mailing list