Skip to content(if available)orjump to list(if available)

Should JavaScript be split into two languages?

hn_throwaway_99

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.

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?

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?

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.

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...

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.)

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.

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.

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.

[1]: https://github.com/tc39/proposal-binary-ast

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.

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.

em-bee

right, making those APIs accessible from WASM is something i am also waiting for.

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.

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.

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:

https://avaloniaui.net/

https://platform.uno/

https://flutter.dev/

Flutter example:

https://flutterweb-wasm.web.app/

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.

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.

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.

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.

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

Still spreading your JS hate from thread to thread I see.

> WebAssembly enables you to use any language. And when you can use any language, why would you use JavaScript?

In which context? I'm doing Kotlin/Java/Rust/C++ for a day job and I'd rather die than use any of those instead of JS for my hobby/exploratory projects.

The amount of bullshit I have to deal with in those languages from tooling to languages themselves is astonishing.

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.

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.

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++.

mediumsmart

absolutely - one for the great minds to play with while running in great circles and one that passes https://jslint.com and is allowed to be on the internet.

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.

davexunit

Yeah it was really concerning to hear someone from Google saying that BigInt doesn't have a use case. It is both used and important!

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.

SigmundA

Would help if it worked with JSON by default.

nephy

I literally use BigInt on the backend every single day at work lol.

Timwi

I would like to see an in-depth treatise explaining why existing bytecode VMs (LLVM, JavaVM and Ecma CLR) were never seriously considered for the world of browsers. These VMs already exist for numerous platforms, have been optimized to death, already have plethoras of languages that compile to them, and beside JavaVM are open source (Ecma CLR exists in the Mono project). I've looked at WebAssembly and I don't understand why it needed to be reinvented from scratch and why it needs to be so limited. We could already be writing web code in Rust, Java, C#, Python, and heck even Haskell, if we had just done that. I know that I'm skipping over the engineering effort required to make this happen but I get a sense that the engineering effort is not the stumbling block. I want to know the details of what is.

Izkata

https://cybercultural.com/p/1995-the-birth-of-javascript/

> As told in JavaScript: The First Twenty Years, Brenden Eich joined Netscape in April 1995.

> [..]

> However, Eich didn’t think he’d have to write a new language from scratch. There were existing options available — such as the research language, Scheme, or a Unix-based language like Perl or Python. So when he joined, Eich “was expecting to implement Scheme in the browser.” But the increasingly fractious politics of the software companies of the day (it was, basically, everyone against Microsoft) soon saw the project take a more creative turn.

> On 23 May 1995, Sun Microsystems launched a new programming language into the world: Java. As part of the launch, Netscape announced that it would license Java for use in the browser. This was all well and good, but Java didn’t really fit the bill for the web. Java is a general-purpose programming language that promised Write Once, Run Anywhere (WORA) functionality, but it was too complicated for web designers and other non-programmers to use. So Netscape decided it needed a scripting language, which was a trendy term at the time for a smaller, easier to learn programming language.

There's a whole lot more interesting stuff but I think that part directly answers most of what you're wondering.

nitwit005

None of them started out with web security in mind.

Look at the Java bytecode, and you'll see it features such things as a goto with an arbitrary offset: https://en.m.wikipedia.org/wiki/List_of_Java_bytecode_instru...

They had to build a verifier that attempts to ensure the bytecode isn't doing anything bad. That proved to be fairly difficult, and comes at a considerable cost.

simonw

My guess is that none of those bytecode VMs were designed with the explicit goal of running untrusted code at global scale in a rock-solid sandbox.

If anything, I expect those existing VMs to slowly be replaced by WebAssembly due to how crucial and complicated that very specific sandbox requirement is - and how useful that is once you have it working reliably.

Personally I never want to run untrusted code on any of my computers outside of a robust sandbox. I look forward to a future where every application I might install runs in a sandbox that I can trust.

koito17

"Secure Java" is something I recall hearing decades ago. No idea if it still exists.

The more important thing to consider, however, is the fact that CLR, JVM, etc. provide internal memory safety whereas Wasm runtimes don't.

e.g. a C program that goes sufficiently out of bounds on an array is guaranteed to segfault in the C runtime, but that runtime error does not necessarily occur on a wasm target. That is to say, the program in the sandbox can have totally strange runtime behavior -- still, defined behavior according to wasm -- although the program has undefined behavior in the source language. In the case of JVM languages, this can't really happen.

mlinksva

SecurityManager? Java's current direction (using the word "integrity" rather than "security", but seems relevant) looks interesting to me https://news.ycombinator.com/item?id=41520246

dboreham

They were. Lots of reasons why it turned out how it turned out. Basically a local minimum in the gradient descent. Computers were much slower is one reason. JVM wasn't open source at the time is another. NIH is another 100 reasons.

koito17

What disqualifies "the JVM" (usually referring to HotSpot implementations) from being considered open source? Are you talking about OpenJ9 or something else?

ameliaquining

A core requirement of WebAssembly was that (ignoring I/O for the moment and considering only the computational core) you should be able to run arbitrary existing code on it, and the effort involved in getting it working should be comparable to porting to a new architecture, not to a new programming language. What this particularly meant, in practice, was that it needed to be a good compilation target for C and C++, since most code is written either in those language or in interpreted languages whose interpreters are written in those languages. (It also needs to support languages that's not true of, like Go, Rust, and Swift, but once you've got C and C++, those languages don't pose major additional conceptual difficulties.)

The JVM and CLR are poor compilation targets for C and C++, because those languages weren't designed to target those runtimes and those runtimes weren't designed to run those languages. (C++/CLI isn't C++.) It's possible to get something working, and a few people have tried, but you run into a lot of impedance mismatches and compatibility issues. I think you would see people run into a lot more problems trying to get their code running on the JVM or CLR than they in fact run into trying to get it running on WebAssembly. (Though I think the CLR is less bad about this than the JVM.)

As for the idea of using LLVM bitcode as an interchange format, we don't have to guess how that would have gone, because it was actually tried! Google implemented this in Chrome and called it PNaCl, and some sites and extensions relied on it for a while. They ultimately withdrew it in favor of WebAssembly. I don't understand all the reasons why it failed, but I think part of the problem is that it ran into a bunch of "the spec is whatever LLVM happens to do" type issues that were real problems for would-be toolchain authors and made the other browser vendors (including Apple, LLVM's de facto primary corporate sponsor) reluctant to support it. WebAssembly has a relatively short and simple standard that you can actually read; writing a WebAssembly interpreter is an undergraduate exercise, though of course writing a highly performant one is much more work.

Also, as far as I can tell, LLVM hasn't at all been optimized to death for the use case of runtime code generation, where the speed of the compiler is about as important as that of the generated code. The biggest dynamic language I know that uses LLVM is Julia, which is a decently big deal, but the overwhelming majority of LLVM is usage is for ahead-of-time compilation of languages like C, C++, Swift, and Rust.

On a bigger-picture note, I'm not sure I at all understand why adopting an existing bytecode language would have made things easier. Yes, it would have been much easier to reuse existing Java code if the JVM had been adopted, or to reuse existing C# code if the CLR had been adopted, but those options are mutually exclusive; the goal was something that would work at least okay for all the languages. Python doesn't have a stable bytecode format, and Rust and Haskell compile to LLVM bitcode (which LLVM has no problem lowering to WebAssembly since WebAssembly was designed to make that straightforward), so I don't see how those languages are in any way disadvantaged by the choice of WebAssembly as the target bytecode language instead of some alternative.

Or are your concerns about I/O? That's a bigger can of worms, and you'd need to explain how you imagine this would work, but the short version is that reusing the interfaces that existing OSes provided would not have worked well, because the browser has a different (and in many ways better) security model.

kaba0

Java is as open-source as it gets (it’s reference implementation, OpenJDK, has the same license as the linux kernel)

And it was used by some browsers, there was just no consensus between different vendors due to politics. The problem largely solved itself by.. only one vendor remaining, chromium.

neonsunset

NIH and CIL is probably an ultra-overkill for browser-based scenarios. It implements a complex type system with all sorts of high-level features that significantly complicate the runtime/compiler. It makes it drastically easier to target but not to write an implementation.

I'm not a huge fan of WASM but it's easy to see that the authors would clearly not want to leave control in the hands of Microsoft or Oracle (and as a result all of us are hostages to Google instead because of evil that is Chromium).

https://ecma-international.org/publications-and-standards/st...

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)

LudwigNagasena

It should have been split into JS and Wasm. Instead they decided to make Wasm a second-class citizen without web API access.

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.

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.

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.

bitwarrior

You didn't read the article.

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.

hoppp

I use bigint all the time. Not adopted? Its not true.