SlideShare a Scribd company logo
1 of 84
Download to read offline
Standardizing JavaScript
Decorators in TC39
Daniel Ehrenberg
Igalia, in partnership with Bloomberg
FullStackFest 2019
About me
● Daniel Ehrenberg
● @littledan
● Live 10 minutes south of here
● Work for Igalia
-- cooperative consultancy
● Mostly work on TC39
What's TC39?
Async/await: New JavaScript feature from...
Who is TC39?
● A committee of Ecma, with…
● JS developers
● JavaScript engines
● Transpilers
● Frameworks, libraries
● Academics
● etc
Meetings
● Every two months
● For three days
● Summarize/review GitHub activity
● Move proposals through stages
TC39 stages
● Stage 1: An idea under discussion
● Stage 2: We're doing this and have a first draft
● Stage 3: Basically final draft; ready to go
● Stage 4: 2+ implementations, tests ⇒ standard
What's new in TC39?
BigInt: Stage 4
const x = 2 ** 53;
⇒ x === 9007199254740992
const y = x + 1;
⇒ y === 9007199254740992
const x = 2n ** 53n;
⇒ x === 9007199254740992n
const y = x + 1n;
⇒ y === 9007199254740993n
const x = 2n ** 53n;
⇒ x === 9007199254740992n
const y = x + 1n;
⇒ y === 9007199254740993n
nstands for BigInt
Optional chaining and
nullish coalescing:
Stage 3
var street = user.address && user.address.street;
// ===>
var street = user.address?.street
var fooInput = myForm.querySelector('input[name=foo]')
var fooValue = fooInput ? fooInput.value : undefined
// ===>
var fooValue = myForm.querySelector('input[name=foo]')?.value
Nullish coalescing:
Stage 3
const response = {
settings: {
nullValue: null,
height: 400,
animationDuration: 0,
headerText: '',
showSplashScreen: false
}
};
const undefinedValue = response.settings?.undefinedValue ?? 'default'; // result: 'default'
const nullValue = response.settings?.nullValue ?? 'default'; // result: 'default'
const headerText = response.settings?.headerText ?? 'Hello, world!'; // result: ''
const animationDuration = response.settings?.animationDuration ?? 300; // result: 0
const showSplashScreen = response.settings?.showSplashScreen ?? true; // result: false
Temporal: Stage 2
let dateTimeAnywhere = new CivilDateTime(2000, 12, 31, 23, 59)
let instantInChicago = dateTimeAnywhere.withZone('America/Chicago'); // ZonedDateTime
dateTimeAnywhere.toString() // 2000-12-31T23:59:00.000000000
// Performing calendar operations such as finding the start of month
dateTimeAnywhere.with({ day: 1 }).toString() // 2000-12-01T23:59:00.000000000
Records and tuples:
Stage 0
const marketData = #[
{ ticker: "AAPL", lastPrice: 195.855 },
{ ticker: "SPY", lastPrice: 286.53 },
];
const updatedData = marketData
with [0].lastPrice = 195.891,
[1].lastPrice = 286.61;
assert(updatedData === #[
{ ticker: "AAPL", lastPrice: 195.891 },
{ ticker: "SPY", lastPrice: 286.61 },
]);
Class features:
Private fields and methods
class Counter extends HTMLElement {
clicked() {
this._x++;
window.requestAnimationFrame(this.render.bind(this));
}
constructor() {
super();
this.onclick = this._clicked.bind(this);
this._x = 0;
}
connectedCallback() { this.render(); }
render() {
this.textContent = this._x.toString();
}
}
window.customElements.define('num-counter', Counter);
class Counter extends HTMLElement {
_x = 0;
_clicked() {
this._x++;
window.requestAnimationFrame(this.render.bind(this));
}
constructor() {
super();
this.onclick = this._clicked.bind(this);
}
connectedCallback() { this.render(); }
render() {
this.textContent = this._x.toString();
}
}
window.customElements.define('num-counter', Counter);
class Counter extends HTMLElement {
#x = 0;
#clicked() {
this.#x++;
window.requestAnimationFrame(this.render.bind(this));
}
constructor() {
super();
this.onclick = this.#clicked.bind(this);
}
connectedCallback() { this.render(); }
render() {
this.textContent = this.#x.toString();
}
}
window.customElements.define('num-counter', Counter);
# is the new _
for strong encapsulation
class PrivateCounter {
#x = 0;
}
let p = new PrivateCounter();
console.log(p.#x); // SyntaxError
class PublicCounter {
_x = 0;
}
let c = new PublicCounter();
console.log(c._x); // 0
Stage 3
What are decorators?
class Counter extends HTMLElement {
#x = 0;
#clicked() {
this.#x++;
window.requestAnimationFrame(this.render.bind(this));
}
constructor() {
super();
this.onclick = this.#clicked.bind(this);
}
connectedCallback() { this.render(); }
render() {
this.textContent = this.#x.toString();
}
}
window.customElements.define('num-counter', Counter);
class Counter extends HTMLElement {
@observed #x = 0;
#clicked() {
this.#x++;
}
constructor() {
super();
this.onclick = this.#clicked.bind(this);
}
connectedCallback() { this.render(); }
render() {
this.textContent = this.#x.toString();
}
}
window.customElements.define('num-counter', Counter);
@defineElement('num-counter')
class Counter extends HTMLElement {
@observed #x = 0;
#clicked() {
this.#x++;
}
constructor() {
super();
this.onclick = this.#clicked.bind(this);
}
connectedCallback() { this.render(); }
render() {
this.textContent = this.#x.toString();
}
}
@defineElement('num-counter')
class Counter extends HTMLElement {
@observed #x = 0;
@bound #clicked() {
this.#x++;
}
constructor() {
super();
this.onclick = this.#clicked;
}
connectedCallback() { this.render(); }
@bound render() {
this.textContent = this.#x.toString();
}
}
import Component from '@ember/component';
import { computed } from '@ember/object';
import { tagName, className } from
'@ember-decorators/component';
@tagName('a')
export default class ExampleComponent
extends Component {
@className
@computed('someKey', 'otherKey')
get bar() {
return
`.${this.someKey}__${this.otherKey}`;
}
}
import Component from
'@ember/component';
import { computed } from
'@ember/object';
export default Component.extend({
tagName: 'a',
classNameBindings: ['bar']
bar: computed('someKey',
'otherKey',
function() {
return
`.${this.someKey}__${this.otherKey}`;
}),
})
Ember
decorators
Popularity
● JS developers are really excited about decorators!
● Used in many frameworks and libraries, e.g.,
○ Angular
○ Ember
○ Salesforce Lightning
○ Polymer/lit-element
○ MobX
● General sentiment: They are used so heavily, are already
there, and should be standardized
Use cases reported
● Original capabilities
○ Decorating classes, fields, methods
● Features of the Stage 2 proposal
○ Interaction with private and fields
○ Scheduling callbacks on construction
● Features not yet proposed
○ mixins, functions, let
Some goals
● Decorators should be fast in implementations:
○ Transpilers
○ JS engines
● Decorators should be easy to use:
○ Using someone else's decorators
○ Writing your own
History of decorator proposals
In 2014/2015: TypeScript "experimental"/Babel "legacy"
How decorators originally worked
2016: Descriptor-based decorators
interface MemberDesciptor {
kind: "property"
key: string,
isStatic: boolean,
descriptor: PropertyDescriptor,
extras?: MemberDescriptor[]
finisher?: (klass): void;
}
interface ClassDesciptor {
kind: "class",
constructor: Function,
heritage: Object | null,
elements: MemberDescriptor[]
}
2017-2019: Descriptor-based proposal grows and evolves
Why descriptor-based decorators, not the original ones?
Both too dynamic and too limited
● [[Set]] vs [[Define]]
● #private
● Extensible over time, how?
● Replacement of property descriptors
● TypeScript vs Babel details
Language-level issues with decorators
Complex to write decorators
● Need to understand Object.defineProperty deeply
○ Even with original decorators
○ Ecosystem abstraction layers
● With Stage 2 proposal, expanded descriptor language
Difficult to extend over time
● Past discussion about "elements"
● Passing new fields back from decorators
● Mixin feature request
Why are descriptor-based decorators slow?
Transpiler implementations
● Slower in practice -- LinkedIn experiment
● Lots of code generated
● Lots of descriptors to generate and process
● Unclear how to generate good code
Native implementations
● Interpreter needs to be fast too
● Generating bytecode similar to static compilers!
● Decorators make many things observable
It's nice if it's easier
to see what's going on
Decorators tend to
have a fixed shape
Built-in decorators and composition
The idea
● Basic building blocks: Built-in decorators
● Compose to make JavaScript-defined decorators
● @decorators are separate, static, lexically scoped
Built-in decorators
● @wrap
● @register
● @expose
● @initialize
Decorators defined in JavaScript
● Compose built-in decorators
● Pass computed arguments to them
@register
@defineElement
import { @defineElement } from
"./defineElement.mjs";
@defineElement('my-class')
class MyClass extends HTMLElement {
/* ... */
}
class MyClass extends HTMLElement {
/* ... */
}
customElements.define(
'my-class', MyClass)
@register
@register(f)
class C { }
class C {
method() { }
}
f(C);
Using @register directly
@register(klass =>
customElements.define(
'my-class', klass))
class MyClass extends HTMLElement {
/* ... */
}
class MyClass extends HTMLElement {
/* ... */
}
customElements.define(
'my-class', MyClass)
Implementing @defineElement
import { @defineElement } from
"./defineElement.mjs";
@defineElement
class MyClass extends HTMLElement {
/* ... */
}
// defineElement.mjs
export decorator @defineElement(name) {
@register(klass =>
customElements.define(
name, klass))
}
@wrap
@logged
import { @logged } from "./logged.mjs";
class C {
@logged
method(arg) {
/* */
}
}
new C().method(1);
// log
class C {
method(arg) {
console.log("log");
/* */
}
}
new C().method(1);
@wrap
class C {
@wrap(f) method() { }
}
class C {
method() { }
}
C.prototype.method =
f(C.prototype.method);
Using @wrap directly
class C {
@wrap(f => {
function wrapped(...args) {
console.log("log");
f.call(this, ...args);
}
return wrapped;
})
method(arg) {
/* */
}
}
class C {
method(arg) {
console.log("log");
/* */
}
}
const prev = C.prototype.method;
C.prototype.method = function(...args) {
console.log("log");
f.call(this, ...args);
}
Implementing @logged
import { @logged } from "./logged.mjs";
class C {
@logged
method(arg) {
/* */
}
}
new C().method(1);
// log
// logged.mjs
export decorator @logged {
@wrap(f => {
function wrapped(...args) {
console.log("log");
f.call(this, ...args);
}
return wrapped;
})
}
Next steps
Recommendations for authors of decorators today
● Just keep using "legacy"/"experimental" decorators
● Goal of this proposal:
For users (not authors) of decorators,
upgrading to standard should be a codemod
Developing consensus
● Not everyone agrees on this version!
● Positive feedback from some
● Concerns raised from others (preferring more dynamic)
● Let's keep discussing!
● TC39 works by consensus
Prototyping this proposal: Plan from here
● Continue discussions towards consensus
● Write specification
● Implement these new decorators in Babel
○ Including some "post-MVP" decorators
● Try out the new decorators
● Collect feedback
● Propose for Stage 3 after some months of stability+use
I regret that we are in an uncomfortable
intermediate state
Help wanted!
Any/all of the following appreciated
Discuss ideas on our
Discourse
Refine proposals in
GitHub issues
Write test262
conformance tests
Implement tooling,
e.g., Babel, or
JS engines, e.g.,
browsers
Prototype them in
your code and tell us
how it went
Write documentation
and educational
materials
Join Ecma and attend
TC39 meetings
But also, take it easy!
● No need to follow this stuff to be a good developer!
● We all do different things
● Nobody understands everything
● Important to have balance when contributing
Conclusion
● Decorators are in progress!
● They will be different from
what you're using now, but
hopefully better
● You can help TC39 move
JavaScript forward
● Daniel Ehrenberg
● @littledan
● https://tc39.es
Thank you!

More Related Content

What's hot

C++: Constructor, Copy Constructor and Assignment operator
C++: Constructor, Copy Constructor and Assignment operatorC++: Constructor, Copy Constructor and Assignment operator
C++: Constructor, Copy Constructor and Assignment operatorJussi Pohjolainen
 
LinkedIn TBC JavaScript 100: Functions
 LinkedIn TBC JavaScript 100: Functions LinkedIn TBC JavaScript 100: Functions
LinkedIn TBC JavaScript 100: FunctionsAdam Crabtree
 
Tutconstructordes
TutconstructordesTutconstructordes
TutconstructordesNiti Arora
 
Architecture for scalable Angular applications (with introduction and extende...
Architecture for scalable Angular applications (with introduction and extende...Architecture for scalable Angular applications (with introduction and extende...
Architecture for scalable Angular applications (with introduction and extende...Paweł Żurowski
 
Categories for the Working C++ Programmer
Categories for the Working C++ ProgrammerCategories for the Working C++ Programmer
Categories for the Working C++ ProgrammerPlatonov Sergey
 
Friend this-new&delete
Friend this-new&deleteFriend this-new&delete
Friend this-new&deleteShehzad Rizwan
 
JavaScript in 2016
JavaScript in 2016JavaScript in 2016
JavaScript in 2016Codemotion
 
Debugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template MetaprogramsDebugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template MetaprogramsPlatonov Sergey
 
Architecture for scalable Angular applications
Architecture for scalable Angular applicationsArchitecture for scalable Angular applications
Architecture for scalable Angular applicationsPaweł Żurowski
 
Home Improvement: Architecture & Kotlin
Home Improvement: Architecture & KotlinHome Improvement: Architecture & Kotlin
Home Improvement: Architecture & KotlinJorge Ortiz
 
Advanced JavaScript Concepts
Advanced JavaScript ConceptsAdvanced JavaScript Concepts
Advanced JavaScript ConceptsNaresh Kumar
 
C# Starter L06-Delegates, Event Handling and Extension Methods
C# Starter L06-Delegates, Event Handling and Extension MethodsC# Starter L06-Delegates, Event Handling and Extension Methods
C# Starter L06-Delegates, Event Handling and Extension MethodsMohammad Shaker
 
constructors and destructors in c++
constructors and destructors in c++constructors and destructors in c++
constructors and destructors in c++HalaiHansaika
 

What's hot (20)

C++: Constructor, Copy Constructor and Assignment operator
C++: Constructor, Copy Constructor and Assignment operatorC++: Constructor, Copy Constructor and Assignment operator
C++: Constructor, Copy Constructor and Assignment operator
 
LinkedIn TBC JavaScript 100: Functions
 LinkedIn TBC JavaScript 100: Functions LinkedIn TBC JavaScript 100: Functions
LinkedIn TBC JavaScript 100: Functions
 
Constructor and destructor
Constructor  and  destructor Constructor  and  destructor
Constructor and destructor
 
Tutconstructordes
TutconstructordesTutconstructordes
Tutconstructordes
 
Classes and objects
Classes and objectsClasses and objects
Classes and objects
 
Architecture for scalable Angular applications (with introduction and extende...
Architecture for scalable Angular applications (with introduction and extende...Architecture for scalable Angular applications (with introduction and extende...
Architecture for scalable Angular applications (with introduction and extende...
 
Categories for the Working C++ Programmer
Categories for the Working C++ ProgrammerCategories for the Working C++ Programmer
Categories for the Working C++ Programmer
 
Friend this-new&delete
Friend this-new&deleteFriend this-new&delete
Friend this-new&delete
 
Oop presentation
Oop presentationOop presentation
Oop presentation
 
JavaScript in 2016
JavaScript in 2016JavaScript in 2016
JavaScript in 2016
 
Constructors & destructors
Constructors & destructorsConstructors & destructors
Constructors & destructors
 
Debugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template MetaprogramsDebugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template Metaprograms
 
Architecture for scalable Angular applications
Architecture for scalable Angular applicationsArchitecture for scalable Angular applications
Architecture for scalable Angular applications
 
Home Improvement: Architecture & Kotlin
Home Improvement: Architecture & KotlinHome Improvement: Architecture & Kotlin
Home Improvement: Architecture & Kotlin
 
Advanced JavaScript Concepts
Advanced JavaScript ConceptsAdvanced JavaScript Concepts
Advanced JavaScript Concepts
 
C# Starter L06-Delegates, Event Handling and Extension Methods
C# Starter L06-Delegates, Event Handling and Extension MethodsC# Starter L06-Delegates, Event Handling and Extension Methods
C# Starter L06-Delegates, Event Handling and Extension Methods
 
constructors and destructors in c++
constructors and destructors in c++constructors and destructors in c++
constructors and destructors in c++
 
Cocoa heads 09112017
Cocoa heads 09112017Cocoa heads 09112017
Cocoa heads 09112017
 
Let's JavaScript
Let's JavaScriptLet's JavaScript
Let's JavaScript
 
C++ manual Report Full
C++ manual Report FullC++ manual Report Full
C++ manual Report Full
 

Similar to Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019)

Performance measurement and tuning
Performance measurement and tuningPerformance measurement and tuning
Performance measurement and tuningAOE
 
Community-driven Language Design at TC39 on the JavaScript Pipeline Operator ...
Community-driven Language Design at TC39 on the JavaScript Pipeline Operator ...Community-driven Language Design at TC39 on the JavaScript Pipeline Operator ...
Community-driven Language Design at TC39 on the JavaScript Pipeline Operator ...Igalia
 
Whats new in ES2019
Whats new in ES2019Whats new in ES2019
Whats new in ES2019chayanikaa
 
Robust C++ Task Systems Through Compile-time Checks
Robust C++ Task Systems Through Compile-time ChecksRobust C++ Task Systems Through Compile-time Checks
Robust C++ Task Systems Through Compile-time ChecksStoyan Nikolov
 
JCConf 2016 - Google Dataflow 小試
JCConf 2016 - Google Dataflow 小試JCConf 2016 - Google Dataflow 小試
JCConf 2016 - Google Dataflow 小試Simon Su
 
Use of Classes and functions#include iostreamusing name.docx
 Use of Classes and functions#include iostreamusing name.docx Use of Classes and functions#include iostreamusing name.docx
Use of Classes and functions#include iostreamusing name.docxaryan532920
 
A New Chapter of Data Processing with CDK
A New Chapter of Data Processing with CDKA New Chapter of Data Processing with CDK
A New Chapter of Data Processing with CDKShu-Jeng Hsieh
 
Visual studio 2008
Visual studio 2008Visual studio 2008
Visual studio 2008Luis Enrique
 
Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2Alessandro Molina
 
Stencil the time for vanilla web components has arrived
Stencil the time for vanilla web components has arrivedStencil the time for vanilla web components has arrived
Stencil the time for vanilla web components has arrivedGil Fink
 
Recoil at Codete Webinars #3
Recoil at Codete Webinars #3Recoil at Codete Webinars #3
Recoil at Codete Webinars #3Mateusz Bryła
 
Integration-Monday-Stateful-Programming-Models-Serverless-Functions
Integration-Monday-Stateful-Programming-Models-Serverless-FunctionsIntegration-Monday-Stateful-Programming-Models-Serverless-Functions
Integration-Monday-Stateful-Programming-Models-Serverless-FunctionsBizTalk360
 
Stencil: The Time for Vanilla Web Components has Arrived
Stencil: The Time for Vanilla Web Components has ArrivedStencil: The Time for Vanilla Web Components has Arrived
Stencil: The Time for Vanilla Web Components has ArrivedGil Fink
 
Introduction to Griffon
Introduction to GriffonIntroduction to Griffon
Introduction to GriffonJames Williams
 
FluentMigrator - Dayton .NET - July 2023
FluentMigrator - Dayton .NET - July 2023FluentMigrator - Dayton .NET - July 2023
FluentMigrator - Dayton .NET - July 2023Matthew Groves
 

Similar to Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019) (20)

Performance measurement and tuning
Performance measurement and tuningPerformance measurement and tuning
Performance measurement and tuning
 
Community-driven Language Design at TC39 on the JavaScript Pipeline Operator ...
Community-driven Language Design at TC39 on the JavaScript Pipeline Operator ...Community-driven Language Design at TC39 on the JavaScript Pipeline Operator ...
Community-driven Language Design at TC39 on the JavaScript Pipeline Operator ...
 
Whats new in ES2019
Whats new in ES2019Whats new in ES2019
Whats new in ES2019
 
Robust C++ Task Systems Through Compile-time Checks
Robust C++ Task Systems Through Compile-time ChecksRobust C++ Task Systems Through Compile-time Checks
Robust C++ Task Systems Through Compile-time Checks
 
JCConf 2016 - Google Dataflow 小試
JCConf 2016 - Google Dataflow 小試JCConf 2016 - Google Dataflow 小試
JCConf 2016 - Google Dataflow 小試
 
Use of Classes and functions#include iostreamusing name.docx
 Use of Classes and functions#include iostreamusing name.docx Use of Classes and functions#include iostreamusing name.docx
Use of Classes and functions#include iostreamusing name.docx
 
A New Chapter of Data Processing with CDK
A New Chapter of Data Processing with CDKA New Chapter of Data Processing with CDK
A New Chapter of Data Processing with CDK
 
Qt Workshop
Qt WorkshopQt Workshop
Qt Workshop
 
Visual studio 2008
Visual studio 2008Visual studio 2008
Visual studio 2008
 
Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2
 
Day 1
Day 1Day 1
Day 1
 
Stencil the time for vanilla web components has arrived
Stencil the time for vanilla web components has arrivedStencil the time for vanilla web components has arrived
Stencil the time for vanilla web components has arrived
 
Recoil at Codete Webinars #3
Recoil at Codete Webinars #3Recoil at Codete Webinars #3
Recoil at Codete Webinars #3
 
Integration-Monday-Stateful-Programming-Models-Serverless-Functions
Integration-Monday-Stateful-Programming-Models-Serverless-FunctionsIntegration-Monday-Stateful-Programming-Models-Serverless-Functions
Integration-Monday-Stateful-Programming-Models-Serverless-Functions
 
Stencil: The Time for Vanilla Web Components has Arrived
Stencil: The Time for Vanilla Web Components has ArrivedStencil: The Time for Vanilla Web Components has Arrived
Stencil: The Time for Vanilla Web Components has Arrived
 
Introduction to Griffon
Introduction to GriffonIntroduction to Griffon
Introduction to Griffon
 
Introduction to angular js
Introduction to angular jsIntroduction to angular js
Introduction to angular js
 
FluentMigrator - Dayton .NET - July 2023
FluentMigrator - Dayton .NET - July 2023FluentMigrator - Dayton .NET - July 2023
FluentMigrator - Dayton .NET - July 2023
 
C#, What Is Next?
C#, What Is Next?C#, What Is Next?
C#, What Is Next?
 
Second Level Cache in JPA Explained
Second Level Cache in JPA ExplainedSecond Level Cache in JPA Explained
Second Level Cache in JPA Explained
 

More from Igalia

A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Building End-user Applications on Embedded Devices with WPE
Building End-user Applications on Embedded Devices with WPEBuilding End-user Applications on Embedded Devices with WPE
Building End-user Applications on Embedded Devices with WPEIgalia
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Automated Testing for Web-based Systems on Embedded Devices
Automated Testing for Web-based Systems on Embedded DevicesAutomated Testing for Web-based Systems on Embedded Devices
Automated Testing for Web-based Systems on Embedded DevicesIgalia
 
Embedding WPE WebKit - from Bring-up to Maintenance
Embedding WPE WebKit - from Bring-up to MaintenanceEmbedding WPE WebKit - from Bring-up to Maintenance
Embedding WPE WebKit - from Bring-up to MaintenanceIgalia
 
Optimizing Scheduler for Linux Gaming.pdf
Optimizing Scheduler for Linux Gaming.pdfOptimizing Scheduler for Linux Gaming.pdf
Optimizing Scheduler for Linux Gaming.pdfIgalia
 
Running JS via WASM faster with JIT
Running JS via WASM      faster with JITRunning JS via WASM      faster with JIT
Running JS via WASM faster with JITIgalia
 
To crash or not to crash: if you do, at least recover fast!
To crash or not to crash: if you do, at least recover fast!To crash or not to crash: if you do, at least recover fast!
To crash or not to crash: if you do, at least recover fast!Igalia
 
Implementing a Vulkan Video Encoder From Mesa to GStreamer
Implementing a Vulkan Video Encoder From Mesa to GStreamerImplementing a Vulkan Video Encoder From Mesa to GStreamer
Implementing a Vulkan Video Encoder From Mesa to GStreamerIgalia
 
8 Years of Open Drivers, including the State of Vulkan in Mesa
8 Years of Open Drivers, including the State of Vulkan in Mesa8 Years of Open Drivers, including the State of Vulkan in Mesa
8 Years of Open Drivers, including the State of Vulkan in MesaIgalia
 
Introducción a Mesa. Caso específico dos dispositivos Raspberry Pi por Igalia
Introducción a Mesa. Caso específico dos dispositivos Raspberry Pi por IgaliaIntroducción a Mesa. Caso específico dos dispositivos Raspberry Pi por Igalia
Introducción a Mesa. Caso específico dos dispositivos Raspberry Pi por IgaliaIgalia
 
2023 in Chimera Linux
2023 in Chimera                    Linux2023 in Chimera                    Linux
2023 in Chimera LinuxIgalia
 
Building a Linux distro with LLVM
Building a Linux distro        with LLVMBuilding a Linux distro        with LLVM
Building a Linux distro with LLVMIgalia
 
turnip: Update on Open Source Vulkan Driver for Adreno GPUs
turnip: Update on Open Source Vulkan Driver for Adreno GPUsturnip: Update on Open Source Vulkan Driver for Adreno GPUs
turnip: Update on Open Source Vulkan Driver for Adreno GPUsIgalia
 
Graphics stack updates for Raspberry Pi devices
Graphics stack updates for Raspberry Pi devicesGraphics stack updates for Raspberry Pi devices
Graphics stack updates for Raspberry Pi devicesIgalia
 
Delegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOS
Delegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOSDelegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOS
Delegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOSIgalia
 
MessageFormat: The future of i18n on the web
MessageFormat: The future of i18n on the webMessageFormat: The future of i18n on the web
MessageFormat: The future of i18n on the webIgalia
 
Replacing the geometry pipeline with mesh shaders
Replacing the geometry pipeline with mesh shadersReplacing the geometry pipeline with mesh shaders
Replacing the geometry pipeline with mesh shadersIgalia
 
I'm not an AMD expert, but...
I'm not an AMD expert, but...I'm not an AMD expert, but...
I'm not an AMD expert, but...Igalia
 
Status of Vulkan on Raspberry
Status of Vulkan on RaspberryStatus of Vulkan on Raspberry
Status of Vulkan on RaspberryIgalia
 

More from Igalia (20)

A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Building End-user Applications on Embedded Devices with WPE
Building End-user Applications on Embedded Devices with WPEBuilding End-user Applications on Embedded Devices with WPE
Building End-user Applications on Embedded Devices with WPE
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Automated Testing for Web-based Systems on Embedded Devices
Automated Testing for Web-based Systems on Embedded DevicesAutomated Testing for Web-based Systems on Embedded Devices
Automated Testing for Web-based Systems on Embedded Devices
 
Embedding WPE WebKit - from Bring-up to Maintenance
Embedding WPE WebKit - from Bring-up to MaintenanceEmbedding WPE WebKit - from Bring-up to Maintenance
Embedding WPE WebKit - from Bring-up to Maintenance
 
Optimizing Scheduler for Linux Gaming.pdf
Optimizing Scheduler for Linux Gaming.pdfOptimizing Scheduler for Linux Gaming.pdf
Optimizing Scheduler for Linux Gaming.pdf
 
Running JS via WASM faster with JIT
Running JS via WASM      faster with JITRunning JS via WASM      faster with JIT
Running JS via WASM faster with JIT
 
To crash or not to crash: if you do, at least recover fast!
To crash or not to crash: if you do, at least recover fast!To crash or not to crash: if you do, at least recover fast!
To crash or not to crash: if you do, at least recover fast!
 
Implementing a Vulkan Video Encoder From Mesa to GStreamer
Implementing a Vulkan Video Encoder From Mesa to GStreamerImplementing a Vulkan Video Encoder From Mesa to GStreamer
Implementing a Vulkan Video Encoder From Mesa to GStreamer
 
8 Years of Open Drivers, including the State of Vulkan in Mesa
8 Years of Open Drivers, including the State of Vulkan in Mesa8 Years of Open Drivers, including the State of Vulkan in Mesa
8 Years of Open Drivers, including the State of Vulkan in Mesa
 
Introducción a Mesa. Caso específico dos dispositivos Raspberry Pi por Igalia
Introducción a Mesa. Caso específico dos dispositivos Raspberry Pi por IgaliaIntroducción a Mesa. Caso específico dos dispositivos Raspberry Pi por Igalia
Introducción a Mesa. Caso específico dos dispositivos Raspberry Pi por Igalia
 
2023 in Chimera Linux
2023 in Chimera                    Linux2023 in Chimera                    Linux
2023 in Chimera Linux
 
Building a Linux distro with LLVM
Building a Linux distro        with LLVMBuilding a Linux distro        with LLVM
Building a Linux distro with LLVM
 
turnip: Update on Open Source Vulkan Driver for Adreno GPUs
turnip: Update on Open Source Vulkan Driver for Adreno GPUsturnip: Update on Open Source Vulkan Driver for Adreno GPUs
turnip: Update on Open Source Vulkan Driver for Adreno GPUs
 
Graphics stack updates for Raspberry Pi devices
Graphics stack updates for Raspberry Pi devicesGraphics stack updates for Raspberry Pi devices
Graphics stack updates for Raspberry Pi devices
 
Delegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOS
Delegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOSDelegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOS
Delegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOS
 
MessageFormat: The future of i18n on the web
MessageFormat: The future of i18n on the webMessageFormat: The future of i18n on the web
MessageFormat: The future of i18n on the web
 
Replacing the geometry pipeline with mesh shaders
Replacing the geometry pipeline with mesh shadersReplacing the geometry pipeline with mesh shaders
Replacing the geometry pipeline with mesh shaders
 
I'm not an AMD expert, but...
I'm not an AMD expert, but...I'm not an AMD expert, but...
I'm not an AMD expert, but...
 
Status of Vulkan on Raspberry
Status of Vulkan on RaspberryStatus of Vulkan on Raspberry
Status of Vulkan on Raspberry
 

Recently uploaded

Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Angeliki Cooney
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKJago de Vreede
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfOverkill Security
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 

Recently uploaded (20)

Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 

Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019)

  • 1. Standardizing JavaScript Decorators in TC39 Daniel Ehrenberg Igalia, in partnership with Bloomberg FullStackFest 2019
  • 2. About me ● Daniel Ehrenberg ● @littledan ● Live 10 minutes south of here ● Work for Igalia -- cooperative consultancy ● Mostly work on TC39
  • 3.
  • 5. Async/await: New JavaScript feature from...
  • 6. Who is TC39? ● A committee of Ecma, with… ● JS developers ● JavaScript engines ● Transpilers ● Frameworks, libraries ● Academics ● etc
  • 7.
  • 8.
  • 9. Meetings ● Every two months ● For three days ● Summarize/review GitHub activity ● Move proposals through stages
  • 10. TC39 stages ● Stage 1: An idea under discussion ● Stage 2: We're doing this and have a first draft ● Stage 3: Basically final draft; ready to go ● Stage 4: 2+ implementations, tests ⇒ standard
  • 11. What's new in TC39?
  • 13. const x = 2 ** 53; ⇒ x === 9007199254740992 const y = x + 1; ⇒ y === 9007199254740992
  • 14. const x = 2n ** 53n; ⇒ x === 9007199254740992n const y = x + 1n; ⇒ y === 9007199254740993n
  • 15. const x = 2n ** 53n; ⇒ x === 9007199254740992n const y = x + 1n; ⇒ y === 9007199254740993n nstands for BigInt
  • 16. Optional chaining and nullish coalescing: Stage 3
  • 17. var street = user.address && user.address.street; // ===> var street = user.address?.street var fooInput = myForm.querySelector('input[name=foo]') var fooValue = fooInput ? fooInput.value : undefined // ===> var fooValue = myForm.querySelector('input[name=foo]')?.value
  • 19. const response = { settings: { nullValue: null, height: 400, animationDuration: 0, headerText: '', showSplashScreen: false } }; const undefinedValue = response.settings?.undefinedValue ?? 'default'; // result: 'default' const nullValue = response.settings?.nullValue ?? 'default'; // result: 'default' const headerText = response.settings?.headerText ?? 'Hello, world!'; // result: '' const animationDuration = response.settings?.animationDuration ?? 300; // result: 0 const showSplashScreen = response.settings?.showSplashScreen ?? true; // result: false
  • 21. let dateTimeAnywhere = new CivilDateTime(2000, 12, 31, 23, 59) let instantInChicago = dateTimeAnywhere.withZone('America/Chicago'); // ZonedDateTime dateTimeAnywhere.toString() // 2000-12-31T23:59:00.000000000 // Performing calendar operations such as finding the start of month dateTimeAnywhere.with({ day: 1 }).toString() // 2000-12-01T23:59:00.000000000
  • 22.
  • 24. const marketData = #[ { ticker: "AAPL", lastPrice: 195.855 }, { ticker: "SPY", lastPrice: 286.53 }, ]; const updatedData = marketData with [0].lastPrice = 195.891, [1].lastPrice = 286.61; assert(updatedData === #[ { ticker: "AAPL", lastPrice: 195.891 }, { ticker: "SPY", lastPrice: 286.61 }, ]);
  • 26. class Counter extends HTMLElement { clicked() { this._x++; window.requestAnimationFrame(this.render.bind(this)); } constructor() { super(); this.onclick = this._clicked.bind(this); this._x = 0; } connectedCallback() { this.render(); } render() { this.textContent = this._x.toString(); } } window.customElements.define('num-counter', Counter);
  • 27. class Counter extends HTMLElement { _x = 0; _clicked() { this._x++; window.requestAnimationFrame(this.render.bind(this)); } constructor() { super(); this.onclick = this._clicked.bind(this); } connectedCallback() { this.render(); } render() { this.textContent = this._x.toString(); } } window.customElements.define('num-counter', Counter);
  • 28. class Counter extends HTMLElement { #x = 0; #clicked() { this.#x++; window.requestAnimationFrame(this.render.bind(this)); } constructor() { super(); this.onclick = this.#clicked.bind(this); } connectedCallback() { this.render(); } render() { this.textContent = this.#x.toString(); } } window.customElements.define('num-counter', Counter);
  • 29. # is the new _ for strong encapsulation
  • 30. class PrivateCounter { #x = 0; } let p = new PrivateCounter(); console.log(p.#x); // SyntaxError class PublicCounter { _x = 0; } let c = new PublicCounter(); console.log(c._x); // 0 Stage 3
  • 32. class Counter extends HTMLElement { #x = 0; #clicked() { this.#x++; window.requestAnimationFrame(this.render.bind(this)); } constructor() { super(); this.onclick = this.#clicked.bind(this); } connectedCallback() { this.render(); } render() { this.textContent = this.#x.toString(); } } window.customElements.define('num-counter', Counter);
  • 33. class Counter extends HTMLElement { @observed #x = 0; #clicked() { this.#x++; } constructor() { super(); this.onclick = this.#clicked.bind(this); } connectedCallback() { this.render(); } render() { this.textContent = this.#x.toString(); } } window.customElements.define('num-counter', Counter);
  • 34. @defineElement('num-counter') class Counter extends HTMLElement { @observed #x = 0; #clicked() { this.#x++; } constructor() { super(); this.onclick = this.#clicked.bind(this); } connectedCallback() { this.render(); } render() { this.textContent = this.#x.toString(); } }
  • 35. @defineElement('num-counter') class Counter extends HTMLElement { @observed #x = 0; @bound #clicked() { this.#x++; } constructor() { super(); this.onclick = this.#clicked; } connectedCallback() { this.render(); } @bound render() { this.textContent = this.#x.toString(); } }
  • 36. import Component from '@ember/component'; import { computed } from '@ember/object'; import { tagName, className } from '@ember-decorators/component'; @tagName('a') export default class ExampleComponent extends Component { @className @computed('someKey', 'otherKey') get bar() { return `.${this.someKey}__${this.otherKey}`; } } import Component from '@ember/component'; import { computed } from '@ember/object'; export default Component.extend({ tagName: 'a', classNameBindings: ['bar'] bar: computed('someKey', 'otherKey', function() { return `.${this.someKey}__${this.otherKey}`; }), }) Ember decorators
  • 37. Popularity ● JS developers are really excited about decorators! ● Used in many frameworks and libraries, e.g., ○ Angular ○ Ember ○ Salesforce Lightning ○ Polymer/lit-element ○ MobX ● General sentiment: They are used so heavily, are already there, and should be standardized
  • 38. Use cases reported ● Original capabilities ○ Decorating classes, fields, methods ● Features of the Stage 2 proposal ○ Interaction with private and fields ○ Scheduling callbacks on construction ● Features not yet proposed ○ mixins, functions, let
  • 39. Some goals ● Decorators should be fast in implementations: ○ Transpilers ○ JS engines ● Decorators should be easy to use: ○ Using someone else's decorators ○ Writing your own
  • 40. History of decorator proposals
  • 41. In 2014/2015: TypeScript "experimental"/Babel "legacy"
  • 43.
  • 44. 2016: Descriptor-based decorators interface MemberDesciptor { kind: "property" key: string, isStatic: boolean, descriptor: PropertyDescriptor, extras?: MemberDescriptor[] finisher?: (klass): void; } interface ClassDesciptor { kind: "class", constructor: Function, heritage: Object | null, elements: MemberDescriptor[] }
  • 46. Why descriptor-based decorators, not the original ones? Both too dynamic and too limited ● [[Set]] vs [[Define]] ● #private ● Extensible over time, how? ● Replacement of property descriptors ● TypeScript vs Babel details
  • 48. Complex to write decorators ● Need to understand Object.defineProperty deeply ○ Even with original decorators ○ Ecosystem abstraction layers ● With Stage 2 proposal, expanded descriptor language
  • 49. Difficult to extend over time ● Past discussion about "elements" ● Passing new fields back from decorators ● Mixin feature request
  • 50. Why are descriptor-based decorators slow?
  • 51. Transpiler implementations ● Slower in practice -- LinkedIn experiment ● Lots of code generated ● Lots of descriptors to generate and process ● Unclear how to generate good code
  • 52. Native implementations ● Interpreter needs to be fast too ● Generating bytecode similar to static compilers! ● Decorators make many things observable
  • 53. It's nice if it's easier to see what's going on
  • 54. Decorators tend to have a fixed shape
  • 55. Built-in decorators and composition
  • 56. The idea ● Basic building blocks: Built-in decorators ● Compose to make JavaScript-defined decorators ● @decorators are separate, static, lexically scoped
  • 57. Built-in decorators ● @wrap ● @register ● @expose ● @initialize
  • 58. Decorators defined in JavaScript ● Compose built-in decorators ● Pass computed arguments to them
  • 60. @defineElement import { @defineElement } from "./defineElement.mjs"; @defineElement('my-class') class MyClass extends HTMLElement { /* ... */ } class MyClass extends HTMLElement { /* ... */ } customElements.define( 'my-class', MyClass)
  • 61. @register @register(f) class C { } class C { method() { } } f(C);
  • 62. Using @register directly @register(klass => customElements.define( 'my-class', klass)) class MyClass extends HTMLElement { /* ... */ } class MyClass extends HTMLElement { /* ... */ } customElements.define( 'my-class', MyClass)
  • 63. Implementing @defineElement import { @defineElement } from "./defineElement.mjs"; @defineElement class MyClass extends HTMLElement { /* ... */ } // defineElement.mjs export decorator @defineElement(name) { @register(klass => customElements.define( name, klass)) }
  • 64. @wrap
  • 65. @logged import { @logged } from "./logged.mjs"; class C { @logged method(arg) { /* */ } } new C().method(1); // log class C { method(arg) { console.log("log"); /* */ } } new C().method(1);
  • 66. @wrap class C { @wrap(f) method() { } } class C { method() { } } C.prototype.method = f(C.prototype.method);
  • 67. Using @wrap directly class C { @wrap(f => { function wrapped(...args) { console.log("log"); f.call(this, ...args); } return wrapped; }) method(arg) { /* */ } } class C { method(arg) { console.log("log"); /* */ } } const prev = C.prototype.method; C.prototype.method = function(...args) { console.log("log"); f.call(this, ...args); }
  • 68. Implementing @logged import { @logged } from "./logged.mjs"; class C { @logged method(arg) { /* */ } } new C().method(1); // log // logged.mjs export decorator @logged { @wrap(f => { function wrapped(...args) { console.log("log"); f.call(this, ...args); } return wrapped; }) }
  • 70. Recommendations for authors of decorators today ● Just keep using "legacy"/"experimental" decorators ● Goal of this proposal: For users (not authors) of decorators, upgrading to standard should be a codemod
  • 71. Developing consensus ● Not everyone agrees on this version! ● Positive feedback from some ● Concerns raised from others (preferring more dynamic) ● Let's keep discussing! ● TC39 works by consensus
  • 72. Prototyping this proposal: Plan from here ● Continue discussions towards consensus ● Write specification ● Implement these new decorators in Babel ○ Including some "post-MVP" decorators ● Try out the new decorators ● Collect feedback ● Propose for Stage 3 after some months of stability+use
  • 73. I regret that we are in an uncomfortable intermediate state
  • 74. Help wanted! Any/all of the following appreciated
  • 75. Discuss ideas on our Discourse
  • 78. Implement tooling, e.g., Babel, or JS engines, e.g., browsers
  • 79. Prototype them in your code and tell us how it went
  • 81. Join Ecma and attend TC39 meetings
  • 82. But also, take it easy! ● No need to follow this stuff to be a good developer! ● We all do different things ● Nobody understands everything ● Important to have balance when contributing
  • 83. Conclusion ● Decorators are in progress! ● They will be different from what you're using now, but hopefully better ● You can help TC39 move JavaScript forward ● Daniel Ehrenberg ● @littledan ● https://tc39.es