stage-0 to stage-4 ECMAscript proposals.
Latest commit 222a5e1 Jan 15, 2017 @hemanth committed on GitHub Merge pull request #28 from phistuck/patch-1
Fixed the indentation and grouping
Permalink
Failed to load latest commit information.
LICENSE Initial commit Mar 9, 2015
README.md Fixed the indentation and grouping Jan 15, 2017

README.md

stage-0 to stage-4 ECMAscript proposals.

TOC:

Stage 0:

Defensible Classes

Stage-0

// const class

const class Point { 
  constructor(x, y) {
    public getX() { return x; }
    public getY() { return y; }
  }
  toString() { 
    return `<${this.getX()}, ${this.getY()}>`;
  }
}

Relationships

Stage-0

x @ r // The object x is in the r relationship with what value?
x @ r = y; // Store that x is in the r relationship with value y.

String.prototype.at

Stage-0

'abc𝌆def'.at(3)
// → '𝌆'

Reflect.isCallable

Stage-0

Reflect.isCallable(argument);

Reflect.isConstructor

Stage-0

Reflect.isConstructor(argument)

Additional metaproperties

Stage-0

function.callee; // function object that is currently being evaluated by the running execution context.
function.count; // number of arguments pass to the function. 
function.arguments; // array containing the actual arguments passed to the function.

Function Bind Syntax

Stage-0

// :: which performs this binding and method extraction.

Promise.resolve(123).then(::console.log);

Do Expressions

Stage-0

// do all the flexible things you can do with statements while still producing a useful result and plugging that back into an expression context.

x = do { let t = f(); t * t + 1 };

64-Bit Integer Operations

Stage-0

// return the high 32 bit part of the 64 bit addition of (hi0, lo0) and (hi1, lo1)
Math.iaddh(lo0, hi0, lo1, hi1);

// return the high 32 bit part of the 64 bit subtraction of (hi0, lo0) and (hi1, lo1)
Math.isubh(lo0, hi0, lo1, hi1);

// return the high 32 bit part of the signed 64 bit product of the 32 bit numbers a and b
Math.imulh(a, b);

// return the high 32 bit part of the unsigned 64 bit product of the 32 bit numbers a and b
Math.umulh(a, b);

Method Parameter Decorators

Stage-0

//decorators that operate on method and constructor parameters.

class MyComponent {
  refresh(@lastRefreshTime timeStamp) { … }
}

export function lastRefreshTime(...) {
  // at minimum, the arguments of this function should contain:
  // - reference to owner of the parameter (the method)
  // - parameter index
  // - parameter name
  // - is parameter a rest parameter?

  // store parameter metadata using the same storage mechanism
  // as the one used for methods
}

Function Expression Decorators

Stage-0

scheduleForFrequentReexecution(@memoize function(value) { 
  value++
});

export function memoize(...) {
  // at minimum, the arguments of this function should contain:
  // - reference to the decorated function expression
  // - arguments passed into the memoize function (if any)

  // wrap the decorated function expression memoization implementation and return it
}

Zones

Stage-0

//a primitive for context propagation across multiple logically-connected async operations

class Zone {
  constructor({ name, parent });

  name;
  get parent();

  fork({ name });
  run(callback);
  wrap(callback);

  static get current();
}

const loadZone = Zone.current.fork({ name: "loading zone" });
window.onload = loadZone.wrap(e => { ... });

Explicit syntactic opt-in for Tail Calls

Stage-0

let factorial = (n, acc = 1) =>
  n == 1 ? acc
         : continue factorial(n - 1, acc * n);

Object enumerables

Stage-0

Object.enumerableKeys(obj); // Ordered list of keys.
Object.enumerableValues(obj); // Ordered list of Values.
Object.enumerableEntries(obj); //Ordered list of key value pairs.

Nested import declarations

Stage-0

describe("fancy feature #5", () => {
  import { strictEqual } from "assert";

  it("should work on the client", () => {
    import { check } from "./client.js";
    strictEqual(check(), "client ok");
  });

  it("should work on the client", () => {
    import { check } from "./server.js";
    strictEqual(check(), "server ok");
  });

  it("should work on both client and server", () => {
    import { check } from "./both.js";
    strictEqual(check(), "both ok");
  });
});

Stage 1:

export * as ns from "mod"; statements

Stage-1

export * as ns from "mod";  // Exporting the ModuleNameSpace object as a named export.

export v from "mod"; statements

Stage-1

export v, {x, y as w} from "mod";

export v, * as ns from "mod";

Observable

Stage-1

// Observable as a Constructor:
function listen(element, eventName) {
    return new Observable(observer => {
        // Create an event handler which sends data to the sink
        let handler = event => observer.next(event);

        // Attach the event handler
        element.addEventListener(eventName, handler, true);

        // Return a function which will cancel the event stream
        return () => {
            // Detach the event handler from the element
            element.removeEventListener(eventName, handler, true);
        };
    });
}

// Observable.of creates an Observable of the values provided as arguments
Observable.of("R", "G", "B").subscribe({
    next(color) {
        console.log(color);
    }
});

// Observable.from converts its argument to an Observable.
Observable.from(["R", "G", "B"]).subscribe({
    next(color) {
        console.log(color);
    }
});

String.prototype.matchAll

Stage-1

var str = 'Hello world!!!';
var regexp = /(\w+)\W*/g;
console.log(str.matchAll(regexp));

/*
[
  {
    0: "Hello ",
    1: "Hello"
    index: 0,
    input: "Hello world!!!"
  },
  {
    0: "world!!!",
    1: "world"
    index: 6,
    input: "Hello world!!!"
  }
]
*/

WeakRefs

Stage-1

// Make a new weak reference.
// The target is a strong pointer to the object that will be pointed
// at weakly by the result.
// The executor is an optional argument that will be invoked after the
// target becomes unreachable.
// The holdings is an optional argument that will be provided to the
// executor when it is invoked for target.
makeWeakRef(target, executor, holdings);

Frozen Realms

Stage-1

class Realm {
  // From the prior Realm API proposal
  const global -> object                // access this realm's global object
  eval(stringable) -> any               // do an indirect eval in this realm

  // We expect the rest of earlier proposal to be re-proposed eventually in
  // some form, but do not rely here on any of the remainder.

  // New with this proposal
  static immutableRoot() -> Realm       // transitively immutable realm
  spawn(endowments) -> Realm            // lightweight child realm
}

Cancelable Promises

Stage-1

new Promise((resolve, reject, cancel) => { ... })
Promise.cancel(cancelation)
promise.then(onFulfilled, onRejected, onCanceled)
promise.cancelCatch(cancelation => { ... })

ArrayBuffer.transfer

Stage-1

//returns a new ArrayBuffer whose contents are taken from oldBuffer
var buf1 = new ArrayBuffer(40);
new Int32Array(buf1)[0] = 42;

var buf2 = ArrayBuffer.transfer(buf1, 80);
assert(buf1.byteLength == 0);
assert(buf2.byteLength == 80);
assert(new Int32Array(buf2)[0] == 42);

var buf3 = ArrayBuffer.transfer(buf2, 0);
assert(buf2.byteLength == 0);
assert(buf3.byteLength == 0);

Math Extensions

Stage-1

// Possible ones:
Math.map
Math.scale
Math.remap
Math.clamp
Math.constrain
Math.toDegrees(double angrad)
Math.toRadians(double angdeg)

of and from on collection constructors

Stage-1

Map.of( ...items );
Map.from( ...items );

Set.of( ...items );
Set.from( ...items );

WeakMap.of( ...items );
WeakMap.from( ...items );

WeakSet.of( ...items );
WeakSet.from( ...items );

Generator arrow functions.

Stage-1

let cat = *() => { yield 'meow'; }

RegExp Named Capture Groups

Stage-1

let {one, two} = /^(?<one>.*):(?<two>.*)$/u.exec('foo:bar');
console.log(`one: ${one}, two: ${two}`);  // prints one: foo, two: bar

Date.parse fallback semantics

Stage-1

//  New grammar should be used as the "fallback" 
//  when date strings do not conform to the 
//  regular Date Time String Format.

String#matchAll

Satge-1

// String.prototype.matchAll(regexp);

let str = 'A\na\nb\nC';
let regex = /^[ac]/im;
let expectedResults = [
  { value: assign(['A'], { input: str, index: 0 }), done: false },
  { value: assign(['a'], { input: str, index: 2 }), done: false },
  { value: assign(['C'], { input: str, index: 6 }), done: false },
  { value: null, done: true }
];

Generator arrow functions (=>*)

Stage-1

// current
x => x * x;
(...) => { statements }
(...) => ( expr )

// proposed generator arrows...

// Irregular
() =*>

// Hostile to ! (async function)
() => * { ...yield... }

// Not good
() => * (yield a, yield b)

// Ok if 1 token
x *=> x * x;

// Bad (ASI)
*() => ...

// Hostile to !
(x) =* {...}

s (dotAll) flag for regular expressions

Stage-1

const re = /foo.bar/s; // Or, `const re = new RegExp('foo.bar', 's');`.
re.test('foo\nbar');
// → true
re.dotAll
// → true
re.flags
// → 's'

/foo.bar/s.test('foo\nbar');
// → true

Promise.try

Stage-1

// Promise.try(function() fn) -> Promise

Stage 2:

Template Literal Revision

Stage-2

// The proposal is about fixing those Illegal token errors, avoid restrictions on escape sequences. 
let document = latex`
\newcommand{\fun}{\textbf{Fun!}}  // works just fine
\newcommand{\unicode}{\textbf{Unicode!}} // Illegal token!
\newcommand{\xerxes}{\textbf{King!}} // Illegal token!

Breve over the h goes \u{h}ere // Illegal token!

function.sent Meta Property

Stage-2

// Avoid ingnoring the first `next` call.
function *adder(total=0) {
   let increment=1;
   do {
       switch (request = function.sent){
          case undefined: break;
          case "done": return total;
          default: increment = Number(request);
       }
       yield total += increment;
   } while (true)
}

let tally = adder();
tally.next(0.1); // argument no longer ignored
tally.next(0.1);
tally.next(0.1);
let last=tally.next("done");
console.log(last.value);  //0.3

Asynchronous Iterators

Stage-2

asyncIterator.next().then(result => console.log(result.value));


for await (let line of readLines(filePath)) {
    print(line);
}

async function *readLines(path) {

    let file = await fileOpen(path);

    try {

        while (!file.EOF)
            yield file.readLine();

    } finally {

        await file.close();
    }
}

Class Property Declarations

Stage-2

// Class instance field
class MyClass {
  myProp = 42;

  constructor() {
    console.log(this.myProp); // Prints '42'
  }
}


// Static property
class MyClass {
  static myStaticProp = 42;

  constructor() {
    console.log(MyClass.myStaticProp); // Prints '42'
  }
}

Public Class Fields

Stage-2

// Class Instance Fields
class ClassWithoutInits {
  myProp;
}

class ClassWithInits {
  myProp = 42;
}
// Class Static Properties

class MyClass {
  static myStaticProp = 42;

  constructor() {
    console.log(MyClass.myStaticProp); // Prints '42'
  }
}

Class and Property Decorators

Stage-2

class C {
  @writable(false)
  method() { }
}

function writable(value) {
  return function (target, key, descriptor) {
     descriptor.writable = value;
     return descriptor;
  }
}

String.prototype.{trimStart,trimEnd}

Stage-2

"    Hey JS!".trimStart(); // "Hey JS!"

"    Hey JS!    ".trimEnd();// "    Hey JS!"

// P.S: trimLeft/trimRight are aliases.

Promise.prototype.finally

Stage-2

somePromise()
.then(() => {})
.catch(() => {})
.finally(() => {})

Legacy RegExp features

Stage-2

RegExpAlloc( newTarget );

RegExpBuiltInExec( R, S );

RegExp.input;

RegExp.prototype.compile( pattern, flags ); // modifications

RegExp Lookbehind Assertions

Stage-2

const str = '1947';

// (?<=(\d+)(\d+))$/ => (947) and (1)
// Greediness proceeds from right to left


// match[1] => 947 and match[2] => 1
// Numbering capture groups

// /(?<=\1(.))/
// Referring to capture groups

// /(?<!.)/
// Negative assertions

Unicode property escapes in RE

Stage-2

const regexGreekSymbol = /\p{Script=Greek}/u;
regexGreekSymbol.test('π');

Private Fields

Stage-2

class Point {
    #x = 0;
    #y = 0;

    constructor() {
        this.#x; // 0
        this.#y; // 0
    }
}

Intl.Segmenter: Unicode segmentation

Stage-2

// Create a segmenter in your locale
let segmenter = Intl.Segmenter("fr", {type: "word"});

// Get an iterator over a string
let iterator = segmenter.segment("Ceci n'est pas une pipe");

// Iterate over it!
for (let {segment, breakType} of iterator) {
  console.log(`segment: ${segment} breakType: ${breakType}`);
  break;
}

// logs the following to the console:
// index: Ceci breakType: letter

Stage 3:

global

Stage-3

// global to rule them all.

var getGlobal = function () {
    // the only reliable means to get the global object is
    // `Function('return this')()`
    // However, this causes CSP violations in Chrome apps.
    if (typeof self !== 'undefined') { return self; }
    if (typeof window !== 'undefined') { return window; }
    if (typeof global !== 'undefined') { return global; }
    throw new Error('unable to locate global object');
};

Rest and Spread properties

Stage-3

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }; // Rest.


let n = { x, y, ...z }; // Spread.

Async-iteration

Stage-3

asyncIterator
  .next()
  .then(({ value, done }) => /* ... */);

Function.prototype.toString revision

Stage-3

// String's parse must contains the same
// function body and parameter list as the original.

O.gOPD({ get a(){} }, "a").get // "function a(){}"

O.gOPD({ set a(b){} }, "a").set // "function a(b){}"

SIMD APIs

Stage-3

/*a meta-variable ranging over all SIMD types:
  Float32x4, Int32x4, Int16x8 Int8x16, Uint32x4, 
  Uint16x8, Uint8x16, Bool32x4, Bool16x8 and Bool8x16. */

Lifting Template Literal Restriction

Stage-3

function tag(strs) {
  strs[0] === undefined
  strs.raw[0] === "\\unicode and \\u{55}";
}
tag`\unicode and \u{55}`

let bad = `bad escape sequence: \unicode`; // throws early error

Shared memory and atomics

Stage-3

var sab = new SharedArrayBuffer(1024);  // 1KiB shared memory

w.postMessage(sab, [sab])

// In the worker:

var sab;
onmessage = function (ev) {
   sab = ev.data;  // 1KiB shared memory, the same memory as in the parent
}

global

stage 3

typeof global; // object, helps in writing a portable code.

import()

stage 3

import(`./language-packs/${navigator.language}.js`) // import(specifier)

Stage 4:

Async Functions

Stage-4

async function chainAnimationsAsync(elem, animations) {
  let ret = null;
  try {
    for(const anim of animations) {
      ret = await anim(elem);
    }
  } catch(e) { /* ignore and keep going */ }
  return ret;
}

Trailing commas in function parameter lists and calls

Stage-4

function foo(
        param1,
        param2,
      ) {}