ಸ್ವಾಗತ!
About Me
ECMAScript
About
@ryzokuken
@ryzokuken
Everybody asks �"What is JavaScript?"
Nobody asks �"How is JavaScript?"
@ryzokuken
Did you know that JavaScript is standardized?
@ryzokuken
What even is a
Standards Body?
1
@ryzokuken
Do you remember 🧀?
@ryzokuken
They’re venues for
unification & uniformization
@ryzokuken
TC39 is the Technical Committee that defines the JavaScript language
@ryzokuken
Delegates
Invited Experts
Contributors, Editors, Reviewers & Community
Who participates?
@ryzokuken
Glossary …
@ryzokuken
How does
TC39 work?
2
@ryzokuken
Consensus-based decisions
Diverse set of people in the committee
Implementers, Practitioners, Community Experts, Academics
Objections and concerns to satisfy everyone
No stakeholder has more power than others, concerns must be rational
@ryzokuken
STAGES
Steps where proposal evolves and receives feedback
4 stages of maturity ← more on this later! 😉
@ryzokuken
TASK GROUPS
TC39 charters sub-groups to work on focus areas:
👷 TG1: The core ECMAScript specification�👷 TG2: Internationalisation�👷 TG3: Security�👷 TG4: Sourcemaps�👷 TG5: Research on Language Standardization 🆕
@ryzokuken
Where
Where
Where
When
6 Plenary Meetings a year
Online or In person
Focus Groups and Incubator Calls
Monthly or Biweekly
TG2 / Editors / Outreach / Proposals / Educators / Tools
Monthly or Biweekly
@ryzokuken
The Process
3
Stage-by-stage
2.7 &
@ryzokuken
STAGE 0
Strawperson
Just an Idea
Explainer, idea under discussion
Oversimplified proposal
STAGE 1
Describe the shape of a solution it’s an idea under discussion
Proposal
Devote time and have a “Champion”
Demos / Polyfills
Major changes
STAGE 1
Signals
Daniel Ehrenberg, Yehuda Katz, Jatin Ramanathan, Shay Lewis, Kristen Hewell Garrett, Dominic Gannaway, Preston Sego, Milo M, Rob Eisenberg
// A VanillaJS Counter
let counter = 0;
const setCounter = (value) => {
counter = value;
render();
};
�const isEven = () => (counter & 1) == 0;
const parity = () => isEven() ? "even" : "odd";
const render = () => element.innerText = parity();
// Simulate external updates to counter...
setInterval(() => setCounter(counter + 1), 1000);
const counter = new Signal.State(0);
const isEven = new Signal.Computed(() => (counter.get() & 1) == 0);
const parity = new Signal.Computed(() => isEven.get() ? "even" : "odd");
STAGE 1
Decimal
Jesse Alama, Andrew Paprocki
0.1 + 0.2 === 0.3
Sync Imports
Pattern Matching
Stabilize
Type Annotations
STAGE 1 🧐
Iterator Unique
Object pick/omit
...and around 80 others
STAGE 2
Draft
Describe syntactic and semantic details
Form spec language - Initial Spec Text
Semantics and API are covered - not completed
TC39 Expects that feature would be developed in future
Experimental
STAGE 2
Async Context
Andreu Botella, Chengzhong Wu, Justin Ridgewell
const asyncVar = new AsyncContext.Variable();
let snapshot
asyncVar.run("A", () => {
snapshot = new AsyncContext.Snapshot();
});
STAGE 2
Iterator Chunking
Michael Ficarra
const digits = () => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].values();
let chunksOf2 = Array.from(digits().chunks(2));
// [ [0, 1], [2, 3], [4, 5], [6, 7], [8, 9] ]
let windowsOf3 = Array.from(digits().windows(3));
// [ [0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6], [5, 6, 7], [6, 7, 8], [7, 8, 9] ]
STAGE 2
Extractors
Ron Buckton
const Foo(y) = x; // instance-array destructuring
const Foo([y]) = x; // nested array destructuring
const Foo({y}) = x; // nested object destructuring
const [Foo(y)] = x; // nesting
const { z: Foo(y) } = x; // ..
const Foo(Bar(y)) = x; // ..
const X.Foo(y) = x; // qualified names (i.e., a.b.c)
Foo(y) = x; // instance-array destructuring
Foo([y]) = x; // nestedarray destructuring
Foo({y}) = x; // nested object destructuring
[Foo(y)] = x; // nesting
({ z: Foo(y) } = x); // ..
Foo(Bar(y)) = x; // ..
X.Foo(y) = x; // qualified names (i.e., a.b.c)
After Stage 2 comes...
Stage 2.7!
@ryzokuken
Why introduce a new stage?
High quality implementations need tests
...but tests can be expensive to write and costly to iterate as the design changes
Test authors want to know when the design is stable ➡ Stage 2.7
Implementers want to know when the tests are ready ➡ Stage 3
🤔
@ryzokuken
STAGE 2.7
Candidate
🧪
Approved in principle but still needs feedback from testing and implementers
We have full spec text!
Reviewers and Editors have signed off the spec text
We will create test262 conformance tests
We might create spec-compliant implementations/polyfills
New!
test262.fyi
Test262(Github)
@ryzokuken
STAGE 2.7
Upsert
Daniel Minor
// Currently
let prefs = new getUserPrefs();
if (!prefs.has("useDarkmode")) {
prefs.set("useDarkmode", true); // default to true
}
// Using getOrInsert
let prefs = new getUserPrefs();
prefs.getOrInsert("useDarkmode", true); // default to true
STAGE 2.7
ShadowRealm
Dave Herman, Mark Miller, Caridy Patiño, Leo Balter, Rick Waldron, Chengzhong Wu
const shadowRealm = new ShadowRealm();
// pluginFramework and pluginScript become available in the ShadowRealm
const [ init, ready ] = await Promise.all([
shadowRealm.importValue('./pluginFramework.js', 'init'),
shadowRealm.importValue('./pluginScript.js', 'ready'),
]);
// The Plugin Script will execute within the ShadowRealm
init(ready);
STAGE 2.7
Math.sumPrecise
Kevin Gibbons
1e20 + 0.1 + -1e20 === 0
Math.sumPrecise([1e20, 0.1, -1e20]) === 0.1
STAGE 3
Recommended for implementation
🥉
Implementation and validation phase�(feedback from implementers, web-compatibility)
Tests have been created for test262
We will only change things if implementation reveals new information
Engines will begin implementing
Browsers may start shipping with or without a flag
STAGE 3
Deferred Evaluation
Yulia Startsev, Nicolò Ribaudo
// This fetches but does NOT evaluate "mod"
import defer * as ns from "mod";
function rarelyUsed () {
// "mod" is lazily evaluated on first use of `ns`
console.log(ns.prop);
}
...
New!
STAGE 3
Temporal
Philipp Dunkel , Maggie Johnson-Pint,
Matt Johnson-Pint, Brian Terlson,�Shane Carr, Ujjwal Sharma, Philip Chimento, Jason Williams, Justin Grant
const yearMonth = Temporal.PlainYearMonth.from({ year: 2020, month: 10 });
yearMonth.toString() // => 2020-10
yearMonth.daysInMonth; // => 31
yearMonth.daysInYear; // => 366
const monthDay = Temporal.PlainMonthDay.from({ month: 7, day: 14 });
const date = monthDay.toPlainDate({ year: 2030 });
date.dayOfWeek; // => 7
date.dayOfYear; // => 195
date.daysInMonth; // => 31
date.daysInYear; // => 365
date.inLeapYear; // => false
let calcDate = Temporal.Now.plainDateISO(); // => 2021-11-29
calcDate.add({ days : 15 }); // => 2021-12-14
calcDate.subtract({ days : 15 }); // => 2021-11-14
calcDate.equals(calcDate); // => true
calcDate.equals(calcDate.add({ days : 2})); // => false
const time = Temporal.Instant.fromEpochSeconds(new Date);
Temporal.TimeZone.from('Europe/Berlin').getOffsetStringFor(time);
// => +01:00
Temporal.TimeZone.from('America/Vancouver').getOffsetStringFor(time)
// => -08:00
Temporal.TimeZone.from('Europe/Moscow').getOffsetStringFor(time);
// => +03:00
STAGE 3
Decorators
Kristen Hewell Garrett
function bound(value, { name, addInitializer }) {
addInitializer(function () {
this[name] = this[name].bind(this);
});
}
class C {
message = "hello!";
@bound
m() {
console.log(this.message);
}
}
let { m } = new C();
m(); // hello!
STAGE 4
Finished
About to be include in the upcoming edition of ECMAScript®
We have two implementations that pass the acceptance tests
We have real-life experience of shipping the feature
We have merged the feature into the Spec��It might not yet be shipping in all mainstream engines
The feature will be included in the next yearly edition, e.g. ES2024
STAGE 4
ArrayBuffer transfer
Shu-yu Guo, Jordan Harband, Yagiz Nizipli
function validateAndWriteSafeAndFast(arrayBuffer) {
// Transfer to take ownership, which implementations can choose to
// implement as a zero-copy move.
const owned = arrayBuffer.transfer();
// arrayBuffer is detached after this point.
assert(arrayBuffer.detached);
await validate(owned);
await fs.writeFile("data.bin", owned);
}
STAGE 4
Set Methods
Kevin Gibbons
let odds = new Set([1, 3, 5, 7, 9, 11, 13]);
let primes = new Set([2, 3, 5, 7, 11, 13]);
let oddPrimes = primes.intersection(odds);
// Set { 3, 5, 7, 11, 13 }
let evenPrimes = primes.difference(odds);
// Set { 2 }
Array Grouping
Atomics.waitAsync
Promise.withResolvers
Well-Formed Unicode Strings
RegExp v flag�+ set notation�+ properties of strings
Resizable & growable ArrayBuffers
STAGE 4 🎉
ArrayBuffer transfer
ECMAScript 2025
ES.next
25th June
esbuild
Case Study
4
@ryzokuken
Problem
@ryzokuken
Moment.js
@ryzokuken
Hobbyists/Tinkerers
⬇️
Subject Matter Experts
PL Designers
@ryzokuken
Hobbyists/Tinkerers
⬇️
Subject Matter Experts
PL Designers
⬇️
Implementers
Security Researchers
@ryzokuken
Hobbyists/Tinkerers
⬇️
Subject Matter Experts
PL Designers
⬇️
Implementers
Security Researchers
@ryzokuken
Students!?
Hobbyists/Tinkerers
⬇️
Experts and PL Designers
⬇️
Implementers
Students and Researchers
⬇️
Users
@ryzokuken
Collaboration & Help
Get involved!
5
@ryzokuken
Write test262 conformance tests
Refine proposals in GitHub issues
Write documentation and educational materials
Provide feedback on GitHub
@ryzokuken
What did Igalia achieve anyway?
@ryzokuken
🙏
ಧನ್ಯವಾದಗಳು