0% found this document useful (0 votes)
4 views

Language Evolution

The document discusses the evolution of JavaScript (JS) and the need for balancing developer productivity with user security, performance, and stability. It outlines the roles of various stakeholders, the complexity introduced by new language features, and proposes a dual-layer approach to standardizing JS, where 'JS0' represents the core language and 'JSSugar' includes features that require tooling for implementation. The goal is to enhance developer experience without compromising user safety and performance, while encouraging broader participation from tooling developers in the standardization process.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Language Evolution

The document discusses the evolution of JavaScript (JS) and the need for balancing developer productivity with user security, performance, and stability. It outlines the roles of various stakeholders, the complexity introduced by new language features, and proposes a dual-layer approach to standardizing JS, where 'JS0' represents the core language and 'JSSugar' includes features that require tooling for implementation. The goal is to enhance developer experience without compromising user safety and performance, while encouraging broader participation from tooling developers in the standardization process.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 54

Language

Evolution
Problems, and
What Can We Do About It?
Shu-yu Guo, Google
Matthew Gaudet, Yulia Startsev, Mozilla
Keith Miller, Michael Saboff, Apple
Peter Hoddie, Moddable
Ross Kirsling, Sony
Oct 2024 TC39
TOC
1. Who?
2. Why? How?
3. What about the users?
4. Let's talk about the future
ONE:
Stakeholders
● Developers (on one side)
○ Frontend for web and native-via-web-tech
○ Backend
○ Embedded
● Implementers (in the middle)
○ Tools (Babel, TypeScript, etc)
○ Engines (SpiderMonkey, JSC, V8, XS, etc)
● End users (on the other side)
○ Users of web browsers
○ Users of apps running (partially) in web browsers
○ Users of apps running (partially) in server runtimes
○ Users of IoT/embedded running JS
Implementers

Devs Users

et al.

Tools Engines
JS is special: outsized everything
● Tens of millions (25 million?) of developers
● Billions of users of software written in JS
● Many maintained independent implementations
2:
We evolve the language to help developers
We want to help developers to be more productive, by…
…better matching their mental models (e.g., FP, OOP, type systems)
…enabling them to more simply express new domains (e.g., ML, finance,
scientific computing, i18n)
…enabling them to build new class of apps with new capabilities (e.g., weak refs,
shared memory)
…letting them use new interfaces (e.g., Wasm)
…reifying common programming patterns they use
…simplifying their lives by removing dependencies and build tools
Specifically, how do we help developers?
● By abstracting away complexity
○ Mental models
○ New domains
○ Reify common patterns
○ Remove dependencies and build tools
● By introducing new abilities
○ New capabilities
○ New interfaces
● By explicit coordination point
○ All of the above
Abstracting away complexity moves it, not removes it
● Complexity is moved from tooling and developer code to language
implementations
● Application-level complexity:
○ Negative impacts limited to application's users
○ Easier and faster to patch
● Implementation-level complexity:
○ Negative impacts are broad; impacts all implementation (e.g. a browser's) users
○ Harder and slower to patch
three:

three:
What do users want?
● Security
○ Prosaic: As a shopper, I want to securely shop, so that I don't have my money stolen
○ Scary: As a person, I want to not be disappeared, so that I go on living my life
● Performance
○ As an impatient person, I want my apps to be fast, so I don't have to reflect on my
impatience as a character flaw
● Stability
○ As a user, I want my apps to keep working, so I can keep using them
● App features

Remember, end users are the implementations' primary customer!


What user impact do new language features have?
● Security: Almost always, negatively impacted
● Performance: Generally, neutral to negatively impacted
● Stability: Sometimes, negatively impacted
● App features: Positively impacted, if developers use the language
feature
Security
Complexity = Security bugs

Sample of recent engine (V8, SM) CVEs (i.e. filed externally):


● BigInts (CVE-2024-7972, CVE-2020-16042) ● Resizable buffers (CVE-2022-3045)
● Class scopes (CVE-2024-7535, CVE-2024-5274) ● WeakRef and FinalizationRegistry (CVE-2022-2158,
● Built-in (Promise) subclassing (CVE-2021-4078, CVE-2023-5728)
CVE-2023-4355) ● Logical assignment (CVE-2021-23954)
● Optimizing super (CVE-2024-2625, CVE-2023-4069, ● Top-level Await (CVE-2022-1529)
CVE-2023-2935, CVE-2022-1134, CVE-2021-38001,
CVE-2021-30517)

(To show you that I am a serious man, the vulnerabilities above are in set in Arial.)

Browser vendors aren't yahoo outfits. This is despite state-of-the-art


security engineering with fuzzing, bounty programs, security reviews, etc.
Security / General Complexity
● VMs are already very complex because of pressure to be fast, and
complexity cross-cuts all of security
● Feels especially bad when complex features don't get adoption
○ Species
○ BigInts
Performance
● New features have guardrails that can't be optimized away
○ let/const TDZ
● Design inherently slow for network
○ ESMs
● Too many allocations that are hard to elide
○ Iterator protocol
Stability
● We're very good with backwards compat. Things that used to work keep
working
● But: Enterprise
○ Freezes browser version
○ Apps that target latest baseline may stop working on Enterprise
■ Firefox experience: nullish coalescing broke some sites
New app features
● New language features should help developers be more productive, so
they can ship (more) new features for their users (faster)
● But native adoption of features is lackluster or sometimes not worth it:
○ Performance regressions (e.g. TDZ, async generators)
○ Use cases never materialized (BigInt)
○ Lack of incentives to stop transpiling
Aren't these negatives to the
user offset by the benefit to
developers?
*
No.

* I mean clearly it's a polarity. This is saying not all wins for devs are necessarily wins for users.
Cost to users is in aggregate
● Complexity belongs at the edges
○ Foundational tech ought to be simple
● JS runtimes are used by billions, a security flaw there has far wider
implications
● User base of each applications are much, much smaller, for vast majority
of apps
○ Notable exceptions exist: WordPress, Facebook, Google, etc
● Complexity cost in runtimes has a storage, memory, and performance cost
to every users regardless of adoption
Goals in tension

Helping
developers Doing right
to be more by users
productive
Goals in tension

Helping
developers Doing right
to be more by users
productive

Where I Where I
think we are think we
today should go
How do we get there?
We need to talk about how we introduce new features

● Broad discussion
● We are going to offer perspectives & a starting point for a solution
What engines want
Engines want to ensure security, performance, and stability for users

Takeaway

Engines are going to be more conservative with new language features


Not proposing new process or demotions!
● Not proposing a new process
● Not proposing we demote any features (including Stage 3)

This is about steering for the future


Taxonomy of new language features
● Syntax
● APIs
● Capabilities
Syntax
Decomposable Functionally intrinsic
Decomposability
● Syntax that can be represented as an API (BigDecimal)
● Syntax that is/can be represented by an API but would benefit from a
different textual representation (Pipeline)
● Syntax where the textual representation enables its function (immutable data
structures i.e. records and tuples syntax)
Language distance Requires static compilation dynamic

● Some syntax additions fit without issue into a language which is dynamically
typed and interpreted
● Some syntax features makes more sense to rely on type information or on a
compile step
APIs
Builtin methods

● Expanding capabilities of existing builtins


● Allowing additional capabilities for existing methods

New Builtins

● Subtypes of existing builtins (usually object)


New Capabilities
Exposing the host system (Machine, OS, Compiler, etc)

● Access to machine types that were impossible before (float)


● Access to information that was obscured (WeakRef / Memory)
● Parallelism (Shared structs)

Exposing the host platform (Web, Node, Embedded, etc)

● Web APIs, WinterCG APIs (Modules Harmony work), TC53, etc


New Capabilities
Opportunity cost of not adding new capabilities is large because the
alternative is "you can't do it"

These are where most of the risk appetite is for implementers


Rough guidance for where the bar is
● New capabilities
● Simple / ease of understanding for implementation for security
● Features that have wide adoption & known performance advantages by
being in engine
● High confidence needed for use cases
● Existence in another language insufficient motivation
What engines want
Engines want to ensure security, performance, and stability for users

Takeaway

Engines are going to be more conservative with new language features


Engines being conservative

Stop evolving the language
So here's a possible solution
for Syntax features
Disclaimer: this possible solution is Google's
preferred solution, not necessarily other
implementers'
Developers have embraced tooling
Authoring JS is now primarily intermediated by tools

● TypeScript continues to grow in popularity for projects hosted on GitHub


● Babel has 50+ million downloads a week
● TypeScript usage outweighs JavaScript in the State of JS survey
● Survey data show from 55% to 99% of developers using frameworks
Tools exist and are widely adopted.
Let's use that fact for a win/win.
Let's standardize JS as the ecosystem uses it
● JS0: the language implemented by the engines
● JSSugar: features that must be compiled by tools to JS0
● For developers, JS = JS0 + JSSugar

(Yes, the names could be better. Indulge them for now, happy to bikeshed
later.)
Implementers

JSSugar
Devs Users
JS0 JS0
et al.

Tools Engines

JSSugar

JS0
Proposal
● Allow future syntax features to be spec'd as desugarings in JSSugar
● Tools count as implementers for JSSugar features
● Future API and capability features go into JS0
○ Though stay tuned!
● Runtimes count as implementers for JS0 features
● There is still one standard
○ Compliant engines support JS0
○ Compliant tools support downleveling JSSugar to JS
This is not a proposal for tools
to do non-standard
extensions!!
This is a proposal calling for
more tooling participation in
TC39 and more standards
compliance among tools.
Proposal
● JS0 can be an "ABI" layer to aid coordination of compiled JSSugar
features for tools
● JSSugar features need to demonstrate they are debuggable at runtime
and is sufficiently supported by source maps
● JSSugar/JS0 boundary is fluid
○ JSSugar feature can move into JS0 over time if there's a clear advantage (as shown by
sufficient experience and data)
● Proposals may be composed of a JSSugar part and a JS0 part
Win/win?
1. Language can improve DX without impacting all users' performance and
security (or being frozen)
○ JSSugar focuses on DX
○ JS0 features focuses on simplicity for security and performance
○ Rough guidance for higher bar from before applies only to JS0
2. Horses for courses
○ JS VM teams poorly staffed for DevRel and listening to broad-spectrum dev feedback,
but are good compiler authors
○ Tool teams are closer to devs
3. Improved runtime security by slowing the increase of the JS attack
surface
Win/win?
4. JS0 features can have fewer guardrails (e.g. TDZ) that are slow and
complex, as those guardrails are better implemented in the tools and in
JSSugar
5. By standardizing features that are expected to be compiled, transpilation
will feel more permanent and better align the tools
6. Given wide adoption of tools, a bi-level JS should not affect workflow of
majority of developers
Win/win?
7. JSSugar features can be less stable – but this is also an advantage to
more easily fix mistakes
8. We should be designing features with "codegen" (transpilation output) in
mind. Developers already consume many features that way
FAQ: What about "1 JS"?
● State of the world is that JS is authored with tools in the loop
● Tool-using developers will care about JS0 in the same way they care
about what version of ES to downlevel today
● Still one standard
FAQ: Why require build tooling?
● Author-directly-for-runtime model is outdated and no longer borne out
by data
● State of JS development today already requires tooling to be productive
& competitive
● No evidence suggesting tooling use would decrease in future
● Aspects of web development already preclude frictionless direct
authoring
○ Secure context require local HTTP server
● Direct authoring can be recovered during development at high
performance cost (CoffeeScript did this)
○ h/t Dan Ehrenberg
FAQ: Won't DevTools will be worse?
● Standard ABI layer is opportunity to improve
debuggability of transpiled features
● Opportunity to require better source map support for
transpiled features during standardization
FAQ: What about proposal XYZ?
● Proposals will be individually considered on their merits as before, with
new framing
● See rough guidance on bar for JS0
Next steps and challenges
● Tooling representation in TC39 needs to improve
● A new TG?
● Nuts & bolts of speccing desugarings?
I'm sure many of
you have many
thoughts

You might also like