Skip to content

Instantly share code, notes, and snippets.

Allen Wirfs-Brock allenwb

Block or report user

Report or block allenwb

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
@allenwb
allenwb / species.md
Last active Nov 18, 2015
A FAQ on the Design of the ECMAScript 2016 @@species protocol
View species.md

####Why is .constructor not good enough? What does doing .constructor[@@species] add?

@@species is an extension point that allows abstract algorithms that may be inherited by (or applied to) various subclasses with differing characteristics to decouple the class of the objects generated by an application of the method from the actual class of the objects the method was applied to. This is a realivately rare situation, but one that does infact occur when developing relatively complex class hierarchies such as a collections hierarchy.

The first known usage of the species pattern that I’m aware of (and the origin of the name species) was in the Smalltalk-80 collection hierarchy. For example, the Smalltalk-80 collection hierarchy includes a class called SortedCollection. SortedCollection is a subclass of OrderedCollection (essentially a double ended queue, similar to a JS Array) except that whenever a new element is added to the collection, the value ordering of the collection is resorted. The familiar operat

View new instantation rationale.md

At the July 2014 TC39 meeting, we presented a sketch of a new object instantiation design that was inspired from posting of Claude Pache. Here's the basic idea, as originally described by Claude:

If a constructor C uses super in its code, let’s say:

  class C extends B {
      constructor(...args) {
          /* 1: preliminary code that doesn't contain calls to a super-method */
          // ...

          /* 2: call to a super-constructor */
@allenwb
allenwb / 0Option2ConstructorSummary.md
Last active Aug 26, 2019
New ES6 constructor features and semantics: Alternative 2 manual super in derived classes
View 0Option2ConstructorSummary.md

New ES6 Constructor Semantics and Usage Examples

Manual super: Alternative Design where subclass constructors do not automatically call superclass constructors

This Gist presents a new design of class-based object construction in ES6 that does not require use of the two-phase @@create protocol.

One of the characteristics of this proposal is that subclass constructors must explicitly super invoke their superclass's constructor if they wish to use the base class' object allocation and initialization logic.

An alternative version of this design automatically invokes the base constructor in most situations.

@allenwb
allenwb / 0option1ConstructorSummary.md
Last active Aug 29, 2015
New ES6 constructor features and semantics: Alternative 1 auto allocation in derived classes
View 0option1ConstructorSummary.md

New ES6 Constructor Semantics and Usage Examples

Auto super: Alternative Design where subclass constructors automatically call their superclass constructors

This Gist presents a new design of class-based object construction in ES6 that does not require use of the two-phase @@create protocol.

One of the characteristics of this proposal is that subclasses constructors automatically super invoke their superclass constructor's object allocation and initialization logic unless the derived constructor expliictly assigns to this.

An alternative version of this proposal eliminates from the design most implicit/automatic invocations of superclass constructors.

In addition to the material below, there is a seperate design rationale covering several key features that are common to both designs.

@allenwb
allenwb / enumerate.js
Created Jul 18, 2014
[[Enumerate]] in JS code
View enumerate.js
function *enumerate(obj) {
if (Object(obj)!==obj) return undefined;
let visited = new Set;
while (obj!==null ) {
for (name of Object.getOwnPropertyNames(obj)) {
if (!visited.has(name)) {
let desc = Object.getOwnPropertyDescriptor(obj,name);
if (desc) {
visited.add(name);
if (desc.enumerable) yield name;
@allenwb
allenwb / gist:e4b7116aefcec840e9cf
Created Jun 20, 2014
experimenting witn alternatives new semantics for ES6
View gist:e4b7116aefcec840e9cf
//The following is essentially the current ES6 spec. for Boolean, expressed in ES code
//$$foo calls are performing spec. level operations that don't have direct ES language equivalents
class Boolean {
static [Symbol.create](.){
//@@create allocates the object with private slots but doesn't do any slot initialization
return $$OrdinaryDateFromConstructor(this,"%BooleanPrototype%",["[[BooleanData]]"]);
// a newly created Boolean instance has undefined as the value of its [[BooleanData]] internal slot.
// the undefined value indicates that the instance has not yet been initialized by the constructor function
}
@allenwb
allenwb / forin.js
Created May 9, 2013
The ES5 for-in requirements expressed as an ES6 generator function
View forin.js
function *forin(obj) {
let processed = new Set();
while (obj!==null) {
let here = Object.getOwnPropertyNames(obj);
for (let i=0; i<here.length; i++) {
let name = here[i];
if (processed.has(name)) continue;
processed.add(name);
let desc = Object.getOwnPropertyDescriptor(obj,name);
if (desc && desc.enumerable) yield name;
View ArrayTransfer.js
Array.prototype.transfer = function transfer(target=0,start=0, end=this.length, fill=missingMarker) {
/*
The sequence of array elements of array from start up to but not including end are transferred within
the array to the span starting at the index target. The length of the array is not modified.
start and end are interpretation the same as for slice,
negative start, end, and target indices are converted to positive indices relative to the lenth of the array.
If end<=start no elements are transfered.
If end>this.length or target+(end-start)>this.length a range error is thrown and no elements are modified.
View ArrayFill.js
Array.prototype.fill = function fill(value,start=0, end=this.length) {
/*
Every element of array from start up to but not including end are assigned value.
start and end are interpretation the same as for slice,
negative start or stop indices are converted to positive indices relative to the lenth of the array.
If end<=start no elements are modified.
If end>this.length and this.length is read-only a range error is thrown and no elements are modified.
If end>this.length and this.length is not read-only, this.length is set to end.
View Object.isAncestorOf
Object.isAncestorOf = function isAncestorOf(parent,child) {
if (child===null || child===undefined) return false;
if (parent === null) return true;
child = Object(child);
var proto = Object.getPrototypeOf(child);
if (proto === parent) return true;
return isAncestorOf(parent,proto);
}
You can’t perform that action at this time.