Erlscripten: Transpiling Erlang to Javascript. Yes, you read it right.

Tags: erlang, blockchain, aeternityblockchain, elixir
Published: 2021-04-14 22:20:41

It is safe to say that Erlang as a language and framework is the most reliable choice out there to build highly stable applications, running the likes of Whatsapp and Discord. Now, there is a transpiler introducing concepts of Erlang to web technology, which would be near impossible to implement manually using Javascript.


![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wsu0eumfaucke1ni19q9.png)

Here at æternity, we’ve envisioned for a long time that running major parts of a blockchain protocol in the context of modern web frameworks would mean a huge leap for the adoption and scalability of distributed ledger technology. What if you could run an ad-hoc blockchain node in your browser, or use state channels to quickly make safe payments using your phone?
 
> As a solid foundation had to be laid for a reliable infrastructure first, that was not conceivable as of yet. Until now.

###Erlscripten is here.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zqxsabamfrt7qf52x8ub.png)

**Erlscripten** (sic not Emscripten!) is a source-to-source transpiler capable of converting most Erlang codebases into semantically equivalent Purescript projects. Purescript is a strongly typed language heavily inspired by Haskell and which compiles down to Javascript. Taking Purescript as an intermediary step, Erlscripten allows you to take your existing Erlang application and easily ship it out to Javascript users — your Erlang code can now run safely in the browser — enabling code sharing between an Erlang backend and the frontend. It is highly interoperable with Javascript — Javascript can easily call the transpiled code and then make use of the results — you can easily map Erlang constructs and types to readily available JS constructs.


**It’s zero hassle** — you point Erlscripten to an existing Rebar3 Erlang project and in result get a compatible spago project ready to be used in existing Purescript/Javascript projects. **While at it, we transpiled the Erlang runtime (ERTS) that allows you to run arbitrary transpiled Erlang code:**

https://github.com/erlscripten/erlps-core

###Purpose

**Besides bringing the components of the æternity blockchain to more platforms and web frameworks, there are two novel use cases for Erlscripten:**


>####1 — Code reuse between Erlang backends and Javascript frontends;

>####2 — The creation of a new paradigm for developing frontend applications.



æternity is a blockchain platform primarily written in Erlang. In the upcoming era of Hyperchains the need for code distribution between frontend and backend applications is high. Therefore we need to move some parts of æternity infrastructure to the clients’ side in order to provide a more reliable and decentralized system. It doesn’t make sense to rewrite our code in Javascript/Rust manually as this would require a lengthy rewrite and then the need to maintain and sync 2 codebases. The high need of interoperability between Erlang and Javascript is where Erlscripten was born. We can transpile what we need and distribute it to the browser where it’s needed. **One side effect of Erlscripten is that it will soon be possible to write Frontend applications directly in Erlang** — Erlang’s actor based programming maps really nicely to existing reactive frameworks.

###Similar projects

We’re not the first ones with the need of Erlang/Javascript interoperability 

— [Elixirscript](https://github.com/elixirscript/elixirscript) is a Elixir to Javascript transpiler with similar goals as our project. The main downside of Elixirscript is the lack of OTP support (Erlang’s main framework for building failsafe applications) — it works on a really small subset of the Elixir language and they need to rewrite the Elixir standard library in Javascript for it to work. In contrast we are OTP compatible — we transpiled the real Erlang standard library from OTP and distributed it open-source: https://github.com/erlscripten/erlps-stdlib (
Erlang Solutions
).


To demonstrate our point we were capable of taking the compiler of our smart contract language (https://github.com/aeternity/aesophia) and converting it to be runnable in the browser: 

https://github.com/erlscripten/erlps-aesophia


We tested the transpiled project and it works! **Demonstrating our point that we have support for advanced OTP constructs including ETS, Erlang’s in-memory database.**


Notably, [Lumen](https://github.com/lumen/lumen) has similar goals to our project, after their project is done it will be much faster than Erlscripten and probably more capable — the downside is that Lumen is in WIP phase and it will take a long time for Lumen to be ready whereas Erlscripten is now and here! Ready to be used!


###Status quo

####What is supported

* Majority of Erlang expression
* Arbitrary arity functions
* Pattern matching
* Records (via tuples)
* Binaries
* Lambdas
* Tail recursion
* Exceptions
* Process dictionaries
* Code server, module loading
* Imports and exports
* Compatibility utilities
* Common errors (function_clause, case_clause, badarity, etc.)

####What is partially supported

* [Erlang’s standard library](https://github.com/erlscripten/erlps-stdlib/) (most essential modules; lists, maps, string, etc.)
* [Erlang builtins](https://github.com/erlscripten/erlps-core) (the list is growing and growing!)
* Rebar project transpilation
* ETS

####What is under development

* Bitstrings
* Leaking variable scopes
* Basic erlang process emulation
* NIFs (will be done through C to WASM compilation)

###Works on the PureScript compiler

The original PureScript turned out not to suffice our use case perfectly. For instance, we had some issues regarding handling [tail call optimization](https://en.wikipedia.org/wiki/Tail_call) which started several discussions and contributions on their GitHub:

* [Pull Request: Trigger TCO even when there are some self references in non-tail positions](https://github.com/purescript/purescript/pull/3968)

* [Pull Request: Support TCO for functions with tail-recursive inner functions](https://github.com/purescript/purescript/pull/3958)

* [Issue: TCO does not trigger in `case` expressions with assign guards](https://github.com/purescript/purescript/issues/3957)

* [Proposal: Take more opportunities to trigger TCO](https://github.com/purescript/purescript/issues/3967)


Some of the problems have been already fixed due to our reports, but some of them haven’t been accepted as they involved some overhead on the performance in the general case. Because of this [we have forked the compiler](https://github.com/erlscripten/purescript) and started adjusting it for our needs ourselves. Our works mainly involve the optimization tweaks and updating the backend to EcmaScript6 (instead of 5). For instance, we have implemented a much more aggressive tail call optimizer, increased strictness of AST traversals and completely rewritten the code generation for pattern match alternatives.

During this work we have spotted some performance bugs and started working on fixing them on our own. One of our patches has already been approved and awaits merging:

* [Fix exponential collapsing of BindingGroups](https://github.com/purescript/purescript/pull/4006)

###Examples:

While we are perfectly aware that neither Erlang nor PureScript are the most common sight to see, we invite you to take a look: Here are some examples of how Erlscripten transforms existing Erlang code into PureScript. The generated code is obviously larger as we need to take care of the type system (PureScript is typed while Erlang is not) and tackle some syntactic sugars. Furthermore, we need to emulate the default error handling and exceptions that are being solved much differently in Erlang in order to preserve compatibility.

####Factorial:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z15rglu3qfopre2khxyh.png)
 
Find the code example here:

https://github.com/erlscripten/erlscripten/blob/main/examples/factorial.erl

####Continuation based list reversal via catamorphic transformation:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iuj7nh1q8qypdhy6j818.png)
 
Find the code example here:

https://github.com/erlscripten/erlscripten/blob/main/examples/list_reverse.erl

##Run Erlang in the browser!

Erlang to PureScript transpiler > https://github.com/erlscripten/erlscripten

>Original article from : 
https://blog.aeternity.com/erlscripten-92c815786987