Should JavaScript be split into two languages?
323 comments
·October 26, 2024hn_throwaway_99
supriyo-biswas
It seems to me that wasm should just support the web/browser API instead of the current trampoline business; this way, JS build tooling can emit wasm files, which is similar to the example you use.
hn_throwaway_99
What's old is new again :)
asm.js came about because it was a very optimizable subset of JavaScript, then it was superseded by WebAssembly, then the proposal in TFA is basically asking for asm.js back, but perhaps the better answer is to make WebAssembly fully support all of what JS could originally do.
This is perhaps why as I get older I sometimes feel like I want to get out of software development and become a goose farmer like that dude on LinkedIn - lots of times feels more like spiraling in circles than actually advancing.
no_wizard
I think it’s much harder to make big leaps as a community with languages and other - relative to the technology stack as a whole - lower level concerns.
Look at the stronghold grip of C/C++ and how long it’s taken Rust to gain a meaningful foothold in those realms for example.
Google wanted to flat replace JS once already, that was the entire origin of Dart. They only pivoted to the cross platform mobile framework as its primary target after it failed to gain traction as a standard
pjmlp
asm.js came about because Mozzilla refused to adopt PNaCL, which is kind of ironic given the existing Firefox market share a decade later.
dmart
I’ve been hearing about access to DOM APIs from WASM for years now. Does anyone know why this is such a difficult problem?
Deukhoofd
They wanted to implement a typing system first so they could transfer complex types with a strict contract first, as large parts of DOM management would benefit enormously from that, and it would be far better to design an API around. This system has been stuck in different iterations for years.
The current active proposal for it is the Component Model: https://component-model.bytecodealliance.org/design/why-comp....
xscott
Because it's already solved from day one and people keep repeating that it's a problem anyways.
Anything you can do in JavaScript, including access to the DOM, can be put into a JavaScript function. You can import that function into a WebAssembly Module, and you can use WebAssembly Memory to transfer large or complicated data as an efficient side channel. It all works.
no_wizard
They’re already moving it that way, it’s not like it isn’t without complexities and such either. WASM isn’t the silver bullet everyone seems to cling to.
I feel like the WASM fervor has more to do with the fact people don’t enjoy using Frontend tools or JavaScript etc. vs looking at the actual utility tradeoffs
singularity2001
>> WASM isn’t the silver bullet everyone seems to cling to.
And it isn’t the silver bullet exactly for the reason that it's horribly complicated to access normal JS objects including strings.xscott
"trampoline business"?
It supports nearly arbitrary imports of anything you want. How much more flexibility do you need? You could provide an `eval` function to run arbitrary code with a small amount of effort.
Is the problem that Emscripten and/or Rust haven't laid it all out on a platter?
binary132
no, people need to be able to program the browser without needing “tooling”
thayne
> because the shippable code isn't bytecode,
But what if it was?
What I would like to see is:
- a bytecode "language" that roughly corresponds to Javascript semantics, and that is what the engines interpret (and JIT compile)
- browsers still include a compiler to compile JS sourcecode to the bytecode. Possibly wasm could work, although it would need a lot more functionality, like native support for GC, and DOM access, etc.
- browsers include a disassmbler/decompiler to improve debugging the bytecode
Then simple sites, and development can use plain JS source, but for higher performance you can just deploy the pre-compiled bytecode.
alpaca128
I am certain this would mainly add problems while not improving performance as websites would just add more stuff on top until it's again on a barely tolerable level, for both the user and the developer who know probably has to manage yet another super simple, blazingly fast tool to keep everything running.
RandomThoughts3
You are getting your history reversed.
Java is a product of the JVM, which was the innovation, not the reverse. A successful language moving post-success to a new byte code format would be as far as I know unprecedented.
The idea that JavaScript is an interpreted language is also fairly shaky. It’s JIT compiled as soon as it arrives to your browser. Honestly, a modern JS engine is not different from any other VM.
The question as you rightfully pointed really is what do you send to the browser and under it lies the fundamental question of what is a browser actually. Is it a way to browse hypertext content or a standardised execution environment?
javajosh
The problem is within that gray area. For enjoyers of vanilla js, like myself, I'd hate it if "core" js got so small that I now started to require a compiler for my ES6 code. If I was in charge I'd say "fine, but the core must be at least as large as ES6" and I'd reserve the right to tweak browser native modules in minor ways (for example, it would be nice to support a SPA syntax where you could export/import modules from within the same page without either a) hacking the global object or b) generating unnecessary resources).
halostatue
The BEAM VM (Erlang, Elixir) does this with what’s called "Core Erlang", used as lower-level targets before compiling to the BEAM primitives.
https://blog.stenmans.org/theBeamBook/#_compiler_pass_core_e...
pier25
Java doesn't run in browsers so the comparison doesn't make sense.
Splitting the language might make sense from an engineering perspective but what about all the extra energy and bandwidth that will be needed?
sshine
JavaScript is two languages:
1) JavaScript, the original assembly language of the internet, does not need new language features.
2) JavaScript, the front-end web development language is a fractal of infinitely many sub-languages that transpile back to ES5.
The proposal, as I read it, is: Let's stop adding front-end web features to the assembly language; it doesn't get easier, better or faster if we change the underlying, slowly adopting and hard-to-optimize foundation.
When you want a new language feature, add it to the fractal part that transpiles back to the part well-supported and highly optimized in existing runtimes. The only loss is that you need to transpile, so your build pipeline becomes non-trivial. But it's either "code assembly" or "get a modern build tool".
anon7000
This isn’t really true on a practical level any more. ES6 support is very widespread (97% of all web users according to caniuse.) That even includes module import syntax!
There are still some new language features that need to be transpiled, but most projects do not need to worry about transpiling cost/let/arrow functions/etc.
I mean even newer features like nullish coalescing and optional chaining are at 93-94% support.
At the end of the day, I would say tools like babel for transpiling are less and less important. Yes, you still use a bundler because the web has a lot of runtime constraints other native applications don’t have (gotta ship a tiny bundle so the page loads fast), but it’s better for the language features to be implemented in the VM and not just faked with more JS.
sshine
Interesting.
I did assess the ES6 coverage of ~97% a month ago.
I just evaluated that while it sounds high, 3% of people is a lot of people to cut off if your JavaScript is essential.
E.g. Firefox sits at ~2.7% browser market share. (Not incidentally the part that doesn't support ES6, but it's a demography the size of my own.)
Our_Benefactors
> 3% of people is a lot of people to cut off if your JavaScript is essential
These are probably the 3% that won’t affect your business much. They’re more likely to be on older hardware and also have less discretionary income. Or browsing on really weird hardware that is also unlikely to lead to a sale.
ianeigorndua
[dead]
peutetre
Better to focus on WebAssembly instead. Bring every language to the web.
JavaScript for some scripting, any other language for bigger applications.
rafaelmn
Did they solve GC and DOM access ? It's been years since it was "just about to happen" and I stopped paying attention in the meantime. But if it had that I agree - it would be ideal if JS was a legacy thing and a saner WASM first class language got to replace it.
Keep the single threaded event loop approach but kill the JS semantics.
peutetre
Garbage collection is solved to the extent that host garbage collection is now available via WasmGC:
https://developer.chrome.com/blog/wasmgc/
https://v8.dev/blog/wasm-gc-porting
But languages like C# want more features in WasmGC:
https://github.com/dotnet/runtime/issues/94420
No direct DOM access yet. You still have to use JavaScript glue code to get at the DOM.
singularity2001
The problem is that they promised that the WasmGC would include the much desired access to JavaScript objects but now this crucial aspect is no longer part of it and postponed again.
davexunit
Wasm GC is shipped in stable releases of all major browsers except for Safari but that will be changing shortly if it hasn't already (my info is a few weeks old.) The important thing to note about Wasm is that all important functionality, such as access to I/O and the DOM, have to arrive in the form of host imports to a Wasm module. With this in mind, thanks to Wasm GC it is possible to do web UIs from Wasm by importing the relevant bits of the DOM API that the module needs. Projects like Hoot (Scheme) and Kotlin port are already demoing such things.
sjrd
> Projects like Hoot (Scheme) and Kotlin port are already demoing such things.
And Scala.js has shipped it. [1] Although technically experimental, it has no known bugs and it has full support of things like manipulating DOM objects from Scala.js-on-Wasm code.
[1] https://www.scala-js.org/news/2024/09/28/announcing-scalajs-...
nikeee
Actually I don't want DOM access and GC for wasm. At least not yet. It overcomplicates a lot and I simply cannot imagine that a GC can be one-size-fits-all languages.
I want fixed-size buffer-backed structs for JS. Basically a DataView as a C struct. This would massively benefit interop and solve some shortcomings of DataView.
There was a proposal for a binary AST for JS several years ago [1]. Why not just use that as JS0? It's separate and can offer new possibilities as well.
Yoric
(I was the tech lead for this proposal)
How would this be useful for a JS0?
rafaelmn
Problem with AST is that it still kind of forces JS semantics which we should be working away from if we're doing this big leap.
em-bee
good point. in a sense webassembly is that minimal very performant language. let javascript and typescript compile to webassembly, and you essentially got what is being proposed here
sshine
WebAssembly could replace JavaScript, the assembly language, once it has reached feature parity.
But there's still far to go. Large parts of the browser API are still not directly available in WASM.
I very much look forward to WASM reaching stability. It's very enjoyable to run Rust code in the browser.
xscott
What parts are not available?
WebAssembly can call arbitrary JavaScript through imports. You could literally provide an `eval` function if you were motivated to.
em-bee
right, making those APIs accessible from WASM is something i am also waiting for.
hn_throwaway_99
I commented this elsewhere, but the funny thing is that asm.js was the precursor to WebAssembly, and this proposal is essentially asking for asm.js back again.
jokethrowaway
Yes and no, there is a significant bundle size problem with wasm which is hard to fix.
I'd rather we just move to native cross platform applications and stop using a document browser to build interactive applications.
What's more likely is that all of this will probably be eclipsed by LLM and virtual assistants - which could be controlled by native apps with a dynamically generated GUI or voice.
I think APIs exposing data and executing functions will fundamentally change what we think the web is.
akira2501
> I'd rather we just move to native cross platform applications and stop using a document browser to build interactive applications.
Go back to garbage "cross platform" UI toolkits and having to help users manage software dependencies on their machine? No thanks.
kaba0
Throwing out the baby with the bath water? There are millions of standardized APIs available in the browser that would be probably impossible to recreate in anything else due to failing consensus.
peutetre
> I'd rather we just move to native cross platform applications and stop using a document browser to build interactive applications
Here you go. Do both native and wasm:
Flutter example:
ec109685
Not that please. The flutter example took 20 seconds to load and the scroll is super choppy.
It’s unfortunate there isn’t a more native “app like” UI toolkit. Especially on mobile, web apps generally are bad and a lot of the reason is trying to shoehorn an app experience onto the dom.
wiseowise
> I'd rather we just move to native cross platform applications and stop using a document browser to build interactive applications.
Cool stuff, let's kill web for good.
fny
Assembly is not a language runtime. Even if you had WebAssembly as the core, you'd still need to compile JavaScript to WebAssembly, manage the GC, etc which all would still suffer from the performance implications mentioned in the article.
Also... do you really think its wise to rewrite v8 to target WebAssembly?
peutetre
It already supports WebAssembly. All browsers do.
Here's a demo of Dart and Flutter compiled to WebAssembly:
https://flutterweb-wasm.web.app/
WebAssembly enables you to use any language. And when you can use any language, why would you use JavaScript?
Google has started migrating parts of Google Sheets to WebAssembly. They're compiling Java to WebAssembly and seeing a 100% performance increase:
https://web.dev/case-studies/google-sheets-wasmgc
Amazon has been migrating its Prime Video app from JavaScript to WebAssembly. They're compiling Rust to WebAssembly and they've seen increased performance and lower memory usage:
https://www.amazon.science/blog/how-prime-video-updates-its-...
wiseowise
[flagged]
RandomThoughts3
Then you add capability to hide the browser chrome and build close to native user experience and we will have truly looped the loop. Think about that: the browser as an intermediation ensuring resources are properly shared and each application is shielded from the others. Everything that’s old is new again. /s
On a serious note I don’t see the point in turning browsers into an OS on top of the OS. I know it’s some kind of Google wet dream so they can suck up even more data than they already do but still. If you want to ship applications, just do that. The sandboxing should be done at the OS level where it belongs.
anonzzzies
I was in your camp, but we truly lost. Almost everyone I know literally ONLY uses a browser for everything. On mobile some things force you app use, but if that weren't the case, people would use it from a browser. Games in browsers, movies, email, anything. So it makes sense to only open a browser in an OS; it is basically what users do anyway.
mircerlancerous
Sounds like the presenters are assuming that everyone must be using JS in the same way they are. As someone who prefers to work in VanillaJS, I'm already frustrated by all the language changes being forced upon me. So maybe I agree with them that fewer changes should be made, but for completely different reasons. I'd rather them work on API improvements so that web apps get closer to parity with native apps. All this other talk is pointless while web apps remain second class IMO
anon7000
What do you mean forced upon you? There is no requirement for you to use new features. If you do, it’s because you or your team thinks it’s more convenient — and it really is! map, filter, arrow functions, scope improvements with const/let, etc. are major language improvements. So is null coalescing and optional chaining. You don’t have to use them, but they do make JS more straightforward to work with.
ojosilva
I think "forced upon" could also read as:
- at work they expect me to write code with the latest features
- my colleagues write code with the latest features and I have to review/extend/build upon using the same style
- the community, books, copilots, LLMs, libraries, tooling are "forcing" all that new stuff upon me
- etc.
o11c
As a dabbler in JS, it jumps out to me that a lot of tools are trying to force ESM, despite the fact that they lack many essential features that other module systems have.
jazzypants
Which features?
dudus
I think the proposal is actually good for people like you.
You can choose to just work with the core and maybe a minimal sugar library. Which will probably be faster and don't include "all the language features that were forced upon you".
tightbookkeeper
This is not what happened in C vs C++.
Kwpolska
> Regarding BigInt, the presentation states that “use cases never materialized.”
Yet every language has either that or BigDecimal. Even if Google's frontend devs haven't found a use, there also exist JS devs outside of Google who certainly have found uses (though possibly more of them on the backend).
Similarly, not every developer has a compilation step in their JS work. And there are places where you can't have one, e.g. in the browser console. Develop the language instead of tons of incompatible tools.
xscott
That part caught my attention too. It reminds me of the discussion to remove complex numbers from Go. Funny enough, compiler writers can't even imagine why you would want BigInt or Complex, because those aren't useful for writing compilers.
Kwpolska
The problem with Google compiler developers is that they will do a search of the google3 repository, find no uses (because Google doesn’t do any advanced math, for example) and declare the language feature to be useless.
Timwi
Which is ironic because I use Google Sheets a lot and occasionally run into problems when it doesn't support BigInt calculations. Sheets is the best excuse Google has for keeping BigInt support in the language.
em-bee
one contributor to the pike programming language when asked why he took the effort to optimize syntactic sugar responded: so that pike users can write simple code and still have it run blazingly fast.
in pike, bigint and int are integrated in such a way that the transition is automatic. there is no overflow but as long as the values fit in an int, that is used internally to keep the code fast.
the-smug-one
That's nice. The implementation of a numerical tower is common in Lisps: https://en.wikipedia.org/wiki/Numerical_tower
xscott
I used LPC a long time ago on an LP Mud, so Pike has always had a fond spot in the back of my mind, even if I don't use it now.
However, that works for int and bigint, but Number (double precision) can represent numbers that BigInt can not, and BigInt can represent numbers which Number can not. There isn't a graceful way to automatically promote/degrade one to the other in all cases, and a silent conversion will do the wrong thing in many cases.
dboreham
That's a general problem: languages end up having features that are only useful for writing compilers, and vice versa.
CottonMcKnight
Example: Sindre Sorhus' FNV library uses BigInt to support hashes up to 1024 bits. It's quite popular (for a hashing algorithm) on NPM, with 80k+ downloads / week.
null
3np
This stood out to me as well. Proper decimal type would be my #1 missing language feature, seconded by a standardized runtime implementation of the same.
null
null
styfle
I used BigInt to implement xxhash recently.
LudwigNagasena
It should have been split into JS and Wasm. Instead they decided to make Wasm a second-class citizen without web API access.
austin-cheney
The problem expressed is fundamentally correct, but the proposed solution is a band-aid, which is worse than not solving the problem at all. The fix provides a long term change with short term benefits. Reliance on tooling will continue to make code instances are the progressively larger and slower until we arrive at this problem again. At some point JavaScript must become a professional language written by adults, people capable of self-organization and measurement, and not be the subject of fashion by people who aren't qualified to program in the first place.
If performance and complexity really are the primary concerns then the language must stop pandering to children. We already know what high performance looks like. I wrote about it here: https://github.com/prettydiff/wisdom/blob/master/performance...
If the goal really is higher performance and lower complexity the most desirable solution is to create a new language with forced simplicity directly in the image of JavaScript, where simple means less and not easy, and transition to that new language slowly over time. Yes, I understand Google went down this road in the past with Dart, but Dart solved for all the wrong problems and thus was dead on arrival. Instead the idea is to take something that works well and shave off all the bullshit reducing it down to the smallest possible thing.
Forced simplicity means absolutely ignoring all vanity/stylistic concerns and instead only focusing on fewer ways of doing things. As an example consider a language that requires strong typing like TypeScript and thus thereby eliminates type coercion. Another example is operators that have a single purpose (not overloaded), single character, and no redundant operators.
Will there be a lot of crying about vanity bullshit... yes, absolutely. Just ignore it because, you cannot reasonably expect to drive above 120mph on a child's tricycle. If people wish to offer their own stylistic considerations they should include performance metrics and explanations how their suggestions reduce quantity of operations without unnecessary abstraction.
dang
The proposal was submitted here but didn't get much attention. Are there other threads?
Language Evolution: Problems, and What Can We Do About It? - https://news.ycombinator.com/item?id=41795190 - Oct 2024 (1 comment)
Proposal of JavaScript becoming a compiled language: JS0 and JSSugar - https://news.ycombinator.com/item?id=41764825 - Oct 2024 (2 comments)
rixtox
This is also a result of the detachment of TC39 and the developer community. Just how many JS developers are participating TC39? I can recall multiple TC39 proposals that didn't even consult opinions from authors of notable open-source stakeholder libraries, and went straight into stage 3.
And btw, the TypeScript tooling scene is far from being able to get standardized. TypeScript is basically a Microsoft thing, and we don't see a single non-official TypeScript tool can do type-checking. And there's no plan to port the official tools to a faster language like Rust. And the tsc is not designed for doing tranditional compiler optimizations. The TypeScript team made it clear that the goal of tsc is to only produce idiomatic JavaScript.
silvestrov
I really don't like it as it is difficult to debug code when the code that runs isn't the code I wrote.
ratorx
This is mostly a solved problem in regular compilers, and sourcemaps etc do currently exist for JS.
I agree that the tooling/UI around this could be better, but by focusing on this approach, things like Typescript get better as well.
ec109685
Are there debuggers that can single step over the transpiled bits so that it feels like the methods are implemented natively? Otherwise, it becomes a mess.
ratorx
I’m not sure if it exists, but it definitely seems doable (a regular debugger has to map instructions to lines of code).
If the browser starts treating JS as assembly, then there would probably be a greater onus for features like this.
wiseowise
> sourcemaps etc do currently exist for JS.
Are those being supplied with every website you use?
sshine
With the right debugging tools, transpiled alternatives to JavaScript are easier to debug than vanilla ES5.
For example: TypeScript's sourceMap [1], Elm's time-travelling debugger [2], Vue.js DevTools [3], just to name a few I've tried. Especially well-typed languages tend to behave well at run-time once they pass type-checking. Or rather, I have not made enough front-end code to discover transpiler bugs.
[1]: https://www.typescriptlang.org/tsconfig/#sourceMap [2]: https://elm-lang.org/news/time-travel-made-easy (2014 [3]: https://devtools.vuejs.org/
tredre3
> transpiled alternatives to JavaScript are easier to debug than vanilla ES5
As easy, certainly. But how are they easier?
sshine
Because debugging better languages affords you more context and more tooling.
Elm's debugger lets you step forwards and backwards in the application's state.
TypeScript's type system lets you catch bugs before you run the code.
Vue.js's DevTools extend the browser's with a component-based overview, so you can interactively see what's going on at a high level of abstraction. (I'm sure something similar exists for most frameworks similar to Vue.js, and possibly even frameworks made in vanilla ES5, I'm just picking one I've tried.)
With vanilla ES5 you get interactive debugging.
normie3000
> With the right debugging tools, transpiled alternatives to JavaScript are easier to debug than vanilla ES5.
So if I agree with GP then I just haven't found the right tooling yet?
shermantanktop
I started with your position (vanilla js 4ever!) and after being dragged into the world of transpilation via typescript/eslint/prettier/webpack/babel/etc I do agree that it’s at least as easy. Not sure about “easier” but my debugging needs are not exotic. The painful part is initially setting up the toolchain.
sshine
If you're happy writing ES5, power to you.
ninetyninenine
No. Javascript should be split into 3 languages and html and css should be split into 20 languages.
Seriously frontend is already the most fragmented and fast changing area of web there is. Don’t split the language.
ttoinou
You wouldn’t see much difference as a user of those tools. And if you’re writing vanilla JS, you’d have less features creeping in over time. So it seems like you would benefit from this kind of change.
ninetyninenine
Yeah but if I change jobs or work on another project then I’d have to learn two standards.
loftyal
Did you read the article? The sugared JS would be a superset of the target JS. So you would only need to learn the sugared.
akira2501
> and fast changing area
Who cares? If backwards compatability is maintained then this fails to have any impact on my experience as a developer. It sounds like the VM maintainers are busy making their own lives hell. Not my problem.
wiseowise
> Who cares?
I do. Maybe if someone programs in one language it's okay for them to keep up with language changes, but if you have to constantly juggle multiple languages it becomes a real chore to stay up to date with every one of them.
akira2501
I use the language. The existence of new language features has not forced me to adopt them. The standard library for browsers is a different story but it is always going to be.
Thankfully.. both maintain reasonable backwards compatability where security is not otherwise implicated.
bitwarrior
You didn't read the article.
tgv
Fuck, no. Everyone's free to make better tooling, but don't standardize it. There's no point. It'll only lead to further fragmentation. Libraries and frameworks will be split between plain JS and whatever this new version will be called. Just freeze the language and be done.
I'd argue that other languages did this (or something similar) to great success, most notably Java.
That is, the Hotspot VM was such a phenomenal engine that lots of other languages sprung up to take advantage of that: Closure, Scala, Kotlin, etc.: https://en.m.wikipedia.org/wiki/List_of_JVM_languages . Even with the Java language itself, syntactic changes happen much more frequently than VM-level bytecode changes.
With an interpreted language like JavaScript, the dividing line is a little grayer, because the shippable code isn't bytecode, it's still just text. But it still seems to make sense to me to target a a "core", directly interpretable language, and then let all the syntactic sugar be precompiled down to that (especially since most JS devs have a compilation step now anyway). Heck, we basically already did this with asm.js, the precursor to WebAssembly.