Lumen – Elixir and Erlang in the Browser
underjord.io
underjord.io
I like Javascript, a lot, but I would very happily see a future where people have more choices about languages to use on the front-end. My only fear was that everything was going to morph into a kind of Java Applets 2.0, where everything would just be a giant VM on top of another VM.
For the most part, languages aren't doing that though, they're putting in the work to do proper integration with "native" browser systems like the DOM/CSS. I'm optimistic about where language efforts like Rust/Erlang/C#/C are headed, I think these projects are going to be really good for the web overall.
this concern is real which is why we didn't just run BEAM c source through a WASM compiler and call it a day. The implementation here is to optimize compilation to WASM and avoid as much overhead as possible. We have footprint requirements for the compiled asset sizes in mind too.
https://adobe-flash.github.io/crossbridge/
> Combine the power, familiarity, and high-performance of C/C++ with the unparalleled reach of the web. With CrossBridge you can bring your native C/C++ from consoles and PCs to over a billion people on the web – across browsers, with no additional install.
"Unreal Engine 3 Support for Adobe Flash Player"
My concern was that WASM would turn into another kind of Flash Player because devs would just cross-compile everything and spit out frames to a canvas instead of engaging with the web as a platform.
I'm happy that's not what Elixir, or Rust, or C++ are doing. Their approach means that the potential benefits of WASM even today are a lot higher than the potential benefits of Flash ever were. And future to plans to do things like share object and function references between WASM and Javascript push that potential even more.
If you're just concerned about taking a native C++ app and treating the web like a compile target, you've missed the point. The point is to take these languages and make them into first-class web citizens.
1. run multiple nodes on one machine (i.e. manually create Web Workers each with their own copy of Lumen); and then
2. write an erl_dist alternative-carrier protocol driver that uses worker.postMessage()?
It's also competing time-wise with simply "compiling Erlang itself to emscripten/WASM", since computing capability will still scale over time in speed and bandwidth and memory capacity to the point that simply "being able to get ALL of Elixir in the browser" will outvalue "being able to run some subset of Elixir in a single-threaded context only in the browser" (assuming performance is not an order of magnitude different).
I was just reading another HN article discussing the fact that OLAP is going away simply because computers have gotten enough memory and databases have gotten fast enough at querying columnar data stores that it's no longer necessary to add the "optimization complexity" of OLAP to get reasonable data analysis performance.
AMD has the Ryzen Threadripper now, 32 cores with 64 threads... If CPU development continues in that direction, this will be a BIG win for Elixir but only if it can take advantage of more than one thread.
That all said, I'm sure a naïve recompilation of Erlang BEAM to emscripten/WASM might not automatically take advantage of those threads properly out-of-the-box due to the abstraction layer, so there'd also have to be some work there to massage the scheduler to use "real" threads "on the metal".
The threads seem really lightweight, but how would some typical frontend benefit from this?
At ElixirConf I built a simple supervisor DOM tree model. When we are ready to implement it for real we're going to experiment with mapping the DOM to a supervisor. Each node being an element. This way events and rendering take place in each node in the supervisor tree. Rendering would be diff based and merged its way back up. Events would be captured as messages in the idiomatic Erlang/Elixir way.
This is all guess work right now and we don't yet know what will be practical vs what sounds good in theory.
However, we are dedicated to the idea that the programming model of the BEAM is one that complex client-side applications will benefit from over what JavaScript current offers.
There is a db_mon-esque implementation within the source and ultimately this is where the demo will live but for now (and the purposes of that demo at ElixirConf) I went in a different direction
Scenic has some interesting properties in that if a specific component has a code problem and fails/crashes, the supervision tree will bring it back to life. I'm curious to see what similar things one could do with Lumen for the web.
Components are already a very popular level of abstraction with Vue and React, probably others. So maybe there are useful things to bring from Scenic.
Asynchronous and event-driven code is already a fact in the browser so working with an ecosystem that is designed for that may prove a better experience.
I'm hopeful. Also, concurrency, staying of the render thread if possible. There's lots of fun to be had there.
Lumen seems to implement OTP patterns so that's why those things work on it.
In Elixir, I can reason about the code being run in one process as though it were synchronous, because it kind of is. But I can do that without blocking anything else, which is also pretty important.
To be fair you can go about it by just filling up a process mail box with tons of messages.
The sample I tried in this post is only an Erlang interpreter. The whole compile chain is not quite ready from what I gather. It should be feasible at later point. I don't see why not.
[1] https://www.reddit.com/r/csharp/comments/ea5dnb/the_nightmar...
More accurately, you write Elixir, it compiles down to Wasm. Wasm is run by your browser as a more machine-friendly format than JS. It may well be faster.