Small but Helpful
Initially, you could only use objects as keys in a WeakMap, but you want the keys to be unique “and symbols were defined as a new immutable way, that cannot be recreated, so having those as a unique key in the weak map makes a lot more sense”, developer advocate and browser engineer Chris Heilmann told us. This integrates symbols more with these new data structures and might well increase usage of them.
“Now you can do a filter or map, and just have a one-liner for something that was super complex in the past.”
This proposal lets developers call a method to change a single element in the array, using with or splice, and get a new array with that single change — or sort and reverse an array into a fresh array but leave the original array unmodified. This is simpler for developers because it makes array and tuple behavior more consistent, Heilmann pointed out. “The inconsistency between whether array prototypes change the original array or not is something that drove me nuts in PHP. You do a conversion, send it to a variable and then there’s nothing in the variable, because some functions don’t change the original one and others do change it. Any consistency we can bring to things so people don’t have to look it up every day is a very good idea. And anything that allows me to not have to deal with index numbers and shift them around is also a good thing!”
Array find from last also does exactly what the name suggests, returning matching elements in an array starting at the end and working back, which can improve performance — or save writing extra code. “If you have a huge array, it’s really beneficial because you don’t have to look through the whole thing or reverse it before you look it up, so you don’t have to make a temporary duplicate — which developers do all the time,” Heilmann explained.
These four proposals are very likely to be everything we see in ECMAScript 2023, which Ehrenberg noted is a small update, but there are also some important larger proposals that have already reached stage three (which means the spec has been agreed, but can’t be developed further without a full test suite and the real world experience of shipping the feature in at least two implementations).
Reaching stage three isn’t a guarantee that a feature will make it into the standard (because the implantations can reveal that changes need to be made). But iterator helpers, Temporal, explicit resource management and decorators are all stage three proposals making good progress that could be on track for ECMAScript 2024.
Like change array by copy and hashbang grammar, this again brings useful options from other languages, because it’s the kind of feature that’s already widely used in languages like Python, Rust and C#.
“I feel like we’re making pretty good progress towards catching up with Python from fifteen or twenty years ago.”
Almost Time for Temporal
Although Temporal reached stage 3 in 2021, it’s been waiting for the Internet Engineering Task Force (IETF) to standardize string formats used for calendar and time zone annotations. While there were hopes that it would be completed in 2022, it’s still in draft stage. However, there are no major open issues and Carsten Bormann, one of the editors of the IETF date format proposal, told The New Stack that he believes it’s ready for IETF last call. The delay has been down to procedural questions about amending RFC 3339, internet timestamps, rather than any issues with Temporal or the IETF date and time formats it will use, and that’s being worked through, he said. “We have wide agreement on the parts that Temporal needs; we just need to clear that process hurdle.”
It’s still possible that there could be, for example, changes to the calendar format Temporal uses, but developers can start using Temporal now with polyfills (although you may not want to use that in production). Once the IETF draft is officially adopted, there will still need to be two implementations before it can reach stage four but a lot of that work is already underway.
“I’m really hopeful that this will be the year when we will see Temporal ship in at least one browser.”
“Hopefully, in the next few months we will be coming to an end with those bug fixes. And I’m really hopeful that this will be the year when we will see Temporal ship in at least one browser.”
While Temporal isn’t one of the priorities for this year’s Interop browser compatibility project, it did get a lot of votes from developers as an API to consider. “This is visible to browsers — to everyone — that this is high priority,” Ehrenberg said.
“A lot of people are using experimental TypeScript decorators or Babel legacy decorators,” Ehrenberg noted: “in either case, you need to explicitly opt into it, but a lot of frameworks do use decorators and do have presets that include them — and those original decorators are a little bit different from what ends up being stage three Decorators.”
“We went through many iterations of the Decorator proposal and we finally arrived at one that we could agree met both the use cases and the transition paths that were needed from previous decorators and the implementability concerns from browsers. We were finally able to triangulate all of that. It does mean that there are some differences, but at the same time we’ve really tried to make sure that the transition is smooth.”
For example, when you export a class that has a decorator, the first Decorators proposal put the decorator before the export keyword — but a later version of the proposal changed the syntax, putting the decorator after the export.
“A lot of the community was pretty upset about the change because it would have transition costs and there were lots of strong opinions in both directions. And at the very last minute, we decided, you know what, you’re allowed to do either — but not both. In one particular exported class declaration, the decorators can come either before or after the exported keyword, because we saw that the transition path from existing use of decorators was important. We want to enable incremental adoption and treat the existing ecosystem as real: we’re not designing this in a vacuum.”
There will be a slight difference in behavior depending on which order you pick: If you put the decorator before the export keyword, then it won’t be included in the
Function.prototype.toString() text. If the decorator comes after export or export default (or is in a class that isn’t exported), it will be included in the string.
Making Resource Management Obvious
“This makes it difficult to translate front-end development skills, where you might primarily work with the DOM, to back-end development, where you might be working with something like Node’s API, and vice versa. This inconsistency also makes it difficult for package authors to build lifetime management into their packages in a way that allows for reuse both on the web and on the server,” the creator of the proposal, Ron Buckton, told us.
Symbol.asyncDispose method in the using declaration.
“If closing the file means persisting something to a database you can make sure that you wait for that persistence to happen,” Ehrenberg explained.
If you need to compose multiple resources that will be used and then disposed of, there are container classes —
AsyncDisposableStack — which Buckton says were inspired by Python’s
AsyncExitStack — that also let you work with existing objects that don’t yet use the new API.
The asynchronous version, awaitusing, was temporarily split off to a separate Async Explicit Resource Management proposal, because the syntax for that wasn’t as easy to decide on. Now it’s been agreed and has also reached stage three, so the proposals are being combined again and implementations are currently underway, Buckton says. According to Palmer:
“This is great for robust, efficient code, to really make sure you’re cleaning up your resources at the correct time.”
The feature is called “explicit” to remind developers that the resource cleanup will be done immediately and explicitly, as opposed to the implicit and somewhat opaque resource management you get with WeakMap, WeakRef, FinalizationRegistry or garbage collection. Using gives you an explicit, well-defined lifetime for an object that you know will be cleaned up in a timely way, so you can avoid race conditions, if you’re closing and reopening a file or committing transactions to a database.
“The garbage collector can run at weird and magical times, and you cannot rely on the timing,” Palmer warned.
“There are a lot of use cases for explicit resource management, from file IO and Stream lifetime management, to logging and tracing, to thread synchronization and locking, async coordination, transactions, memory management/resource pooling, and more,” Buckton said.
It will be particularly important for resources that have a significant impact on performance, but also drain battery. “I’m hoping that, as this proposal gets adopted by various hosts, we’ll soon be able to use ‘using’ and ‘await using’ with WebGPU and other DOM APIs where resource lifetime and memory management are extremely important, especially on mobile devices.”
Building on What’s New
Having proposals become part of ECMAScript doesn’t mean they don’t carry on developing, as implementers get more experience with them — and as new language features offer ways to improve them.
After a good many years, class fields (including private fields) was included in ECMAScript 2022, “but even though they’ve been shipping in browsers for years, some of the Node community found that there were some performance penalties in using these,” Palmer told us. To address that, Bloomberg funded Igalia to optimize private field performance in V8. “Now private fields access is now at least as fast as public fields and sometimes it’s even faster.”
Other work made it easier for developers to work with private fields by making them accessible inside the Chrome developer tools. From the top level of the console, you can now jump into private fields or look into them while inspecting an object. That doesn’t break any security boundaries, Palmer noted, because you’re in a development environment: “it makes life easier for the developer, and they are entitled to see what’s inside the class”.
In the future, Ehrenberg suggested, there might be a capability for authorized code to look into private fields, based on the stage three decorators proposal, which has features that aren’t in the existing decorators features in Babel and TypeScript. “When you decorate a private field or method, that decorator is granted the capability to look at that private field or method, so it can then share that capability with some other cooperating piece of code,” he explained.
“The new decorators provide a path towards more expressive private fields.”