Skip to content

Instantly share code, notes, and snippets.

// Sketch for exposing [[Call]] and [[Construct]] machinery to JavaScript
// 1. First, let's add the ability to make any object callable with a __call__
// property (using double underscores for some quick strawman syntax).
// Let __target__ be the object that is being called.
var container = { obj: {} };
container.obj.__call__ = function() {
console.log('this = ' + this + ', __target__ = ' + __target__);

If we make call constructors static and inherited, then maybe the name call constructor becomes a bit odd.

  1. The best alternative I could come up with is static constructor:

    class Base {
      static constructor() { return new this(); }
    }

Call constructor should be static and inherited

I'd like to argue that call constructors should behave like static methods and be inherited, because it would be surprising if they didn't.

Here's a use case:

We can currently use static methods to instantiate classes, as an alternative to new:

#include <iostream>
class A {
public:
static void do_something() { std::cout << "yay\n"; }
};
class B : public A {
};
class A
def self.do_something
p 'yay'
end
end
class B < A
end
B.do_something

Re https://github.com/nikomatsakis/typed-objects-explainer/blob/master/valuetypes.md (recent TC39 notes):

I wonder if the immutability requirement can be dropped. To make this work, assignment of value types (color2 = color1) would need to always copy, never be by-reference.

In C++ for example, the complex number class has value semantics (assignment creates a copy, equality compares its constituent values), and yet you can mutate it with c.real(5.0) (sets real part). Similar for vector, which can be mutated with v.push_back(10). This is really no different than int having value semantics but also being mutable (++n). I'm a big fan of C++'s semantics, as they allow you to construct complex objects by repeatedly mutating them and still get value s

JavaScript is currently lacking user-defined types with "value semantics", by which I mean

  • equality and comparison are by value, not by object identity (this includes usage as keys in Map/Set), and
  • assignment creates a copy.

Some use cases not yet covered by Niko's ValueType proposal:

  1. Value semantics for mutable types (https://gist.github.com/joliss/7ca89af5947ddf7c9f57)

  2. Value semantics for variable-sized (heap-allocated) objects. Examples:

var rootNode = require('broccoli-root-node');
var Watched = rootNode.Watched, Unwatched = rootNode.Unwatched;
// Refers to the ./lib directory on disk, and watches it.
var lib = new Watched('lib');
// Refers to the ./bower_components/jquery directory, but does not watch it.
var jquery = new Unwatched('bower_components/jquery');
function CachingWriter(inputTrees, options) {
if (Array.isArray(inputTrees)) {
if (this.enforceSingleInputTree) { // <---- in ES6, `this` is not defined before super
throw new Error('You passed an array of input trees, but only a single tree is allowed.');
}
inputTrees = inputTrees;
} else {
inputTrees = [inputTrees];
}
Plugin.call(this, inputTrees);
@joliss
joliss / .bashrc
Last active August 29, 2015 14:26
glog() {
# requires git 1.8.3 for %C(auto) syntax
git log --graph --date=short --pretty="%Cblue%ad%Creset %C(auto)%h %Cblue%an%Creset%C(auto) %s __REFS:%d" "$@" \
| perl -pe 's/__REFS:[^(]*\(([^)]+)\).*/$refs=$1; $refs=~s{, }{ }g; $refs=~s{tag: }{}g; $refs/e' \
| less;
}
gl() {
glog "$@" | head -n 10;
}