In recent years, JavaScript has grown considerably in size. In this talk, we’ll explore what features are still missing and what features may not be needed.
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 1/46 Future JavaScript: Future JavaScript: what is still missing? what is still missing? JS Kongress, Munich, 2019-03-11 JS Kongress, Munich, 2019-03-11
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 2/46 What is this talk about? What is this talk about? JavaScript has grown considerably in recent years, starting with ES6/ES2015. Already quite well rounded: modules, async (incl. async iteration), etc. What features are still missing? Details: My opinion Most important features only Others may also be useful (risk: bloat) (Mostly) based on officially proposed features
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 3/46 Background: How is Background: How is JavaScript designed? JavaScript designed?
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 4/46 TC39 process TC39 process TC39 (Ecma Technical Committee 39): evolves JavaScript Process is agile: focus is on features, not on ECMAScript releases. Feature proposals go through stages from 0 (strawman) to 4 (finished). Yearly releases of ECMAScript versions (starting with ES2016) Comprise whatever features are finished
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 8/46 Comparing by value (2/2) Comparing by value (2/2) Useful: comparing objects by value (“object value types”). Create a new kind of objects. How? Possibility: new object literals, new Array literals Possibility: new kind of class definition [Currently no proposal] > #{x: 1, y: 4} === #{x: 1, y: 4} true > #['a', 'b'] === #['a', 'b'] true @[ValueType] class Point { // ··· }
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 14/46 Categorizing values Categorizing values Problems with the status quo: Must decide between typeof and instanceof typeof quirks: typeof null is 'object' typeof a function is 'function' (not 'object') instanceof does not work with objects from other realms (frames etc.) May be fixable via a library (WIP of mine).
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 20/46 Pipeline operator Pipeline operator Two competing proposals. We look at Smart Pipelines. Consider: Pipeline operator (more intuitive): Equivalent: const y = h(g(f(x))); const y = x |> f |> g |> h; f(123) 123 |> f
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 23/46 Concurrency Concurrency Current de-facto standard (browsers, Node.js): Worker API Disadvantage: heavyweight – each Worker has its own realm (with global variables etc.). More lightweight concurrency would be nice.
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 27/46 Standard library: modules instead of Standard library: modules instead of namespace objects (3/3) namespace objects (3/3) Benefits: JavaScript becomes more modular (note: also possible via “lazy” namespace objects): Possibly faster startup time Possibly reduced memory consumption Calling imported functions is faster than calling functions in properties : Explores first steps To be determined: exact functionality Stage 1 proposal
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 28/46 Standard library: helpers for iterables Standard library: helpers for iterables (sync and async) (1/3) (sync and async) (1/3) Currently: must convert iterables to Arrays. Better – operations that work with iterables (inspiration: Python’s itertools): const iterable = new Set([-1, 0, -2, 3]); const filteredArray = [...iterable].filter(x => x >= 0); assert.deepEqual(filteredArray, [0, 3]); const filteredIterable = filter(iterable, x => x >= 0); assert.deepEqual( // Only convert iterable to Array to check what’s in it [...filteredIterable], [0, 3]);
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 29/46 Standard library: helpers for iterables Standard library: helpers for iterables (sync and async) (2/3) (sync and async) (2/3) More examples: const iterable = new Set([-1, 0, -2, 3]); // Count elements in an iterable assert.equal(count(iterable), 4); // Create an iterable over a part of an existing iterable assert.deepEqual( [...slice(iterable, 2)], [-1, 0]);
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 30/46 Standard library: helpers for iterables Standard library: helpers for iterables (sync and async) (3/3) (sync and async) (3/3) More examples: [Currently no proposal] // Number the elements of an iterable for (const [i,x] of zip(range(0), iterable)) { console.log(i, x); } // Output: // 0, -1 // 1, 0 // 2, -2 // 3, 3
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 31/46 Standard library: immutable data Standard library: immutable data Support for non-destructively transforming data. Existing examples: : lightweight; works with normal objects & Arrays. : more powerful and heavyweight; has its own data structures. [Currently no proposal] Immer Immutable.js
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 32/46 Standard library: Better support for Standard library: Better support for date times date times Stage 2 proposal: – better date time API. temporal const dateTime = new CivilDateTime(2000, 12, 31, 23, 59); const instantInChicago = dateTime.withZone('America/Chicago');
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 35/46 Optional chaining: pros and cons Optional chaining: pros and cons Pro: concise Cons: Deep nesting should be avoided (harder to change) Tolerance can hide problems Alternatives: Helper functions that extract data Pre-process (clean up) input data before working with it
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 36/46 Really needed: operator overloading? Really needed: operator overloading? Infix function application may be enough: Benefits: Compared to operator overloading: Simple mechanism Not limited to built-in operators Compared to normal function application: Nested expressions remain readable: import {BigDecimal, plus} from 'big-decimal'; const bd1 = new BigDecimal('0.1'); const bd2 = new BigDecimal('0.2'); const bd3 = bd1 @plus bd2; // plus(bd1, bd2) a @ plus b @ minus c @ times d times(minus(plus(a, b), c), d)
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 38/46 Chained exceptions Chained exceptions Indicate cause of a custom error new ChainedError(msg, origError)
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 40/46 Escaping text for regular expressions Escaping text for regular expressions Use case: replacing a plain text multiple times. > const re = new RegExp(RegExp.escape(':-)'), 'ug'); > ':-) :-) :-)'.replace(re, ' ') ' '
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 41/46 Array.prototype.get() Array.prototype.get() for for negative indices negative indices > ['a', 'b'].get(-1) 'b'
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 42/46 As-patterns for matching and As-patterns for matching and destructuring destructuring Proposal: function f(...[x, y] as args) { if (args.length !== 2) { throw new Error(); } // ··· }
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 45/46 Take-aways Take-aways Current JavaScript is already a fairly well-rounded language. Main wishes: Value types (object that are compared by value) BigInts, (Big)Decimals Pipeline operator Lightweight concurrency Bigger standard library
3/11/2019 future-js.md http://localhost:63578/future-js.html?print-pdf#/ 46/46 Further reading Further reading Blog post: My JS books (free online): Download slides: 2ality.com/2019/01/future-js.html exploringjs.com speakerdeck.com/rauschma/