V0.16 – Gleam Compiles to JavaScript

by

Gleam is a form safe and scalable language for the Erlang virtual machine, and
as of on the present time’s v0.16.0 commence Gleam compiles to JavaScript as properly!

Disclose me!

What’s the introduction of a new draw to write down front kill web code without some
cliché examples?

Right here’s a assortment of interactive widgets you’ve potentially seen countless instances
prior to, alongside with their Gleam offer code and the JavaScript it compiles into.

In the interest of brevity we skip error coping with in these examples and exhaust
moderately mercurial-and-dirty form definitions of the JavaScript capabilities they import.
In valid Gleam packages we would place a question to those JavaScript bindings to stay internal
shared libraries, but these examples desires to be ample to come up with a taste of
what Gleam can compose with JavaScript.


Hi there, world!

Sigh their own praises Gleam offer
pub fn significant() {
  let enter = query_selector("[data-hello-input]")
  let express = query_selector("[data-hello-display]")
  let sync = fn() {
    let textual instruct = accumulate(from: enter, property: "value")
    role("innerText", on: express, to: textual instruct)
  }
  role("oninput", on: enter, to: sync)
}
exterior form Sigh
exterior fn query_selector(String) -> Sigh =
  "" "document.querySelector"
exterior fn accumulate(from: Sigh, property: String) -> String =
  "" "Mediate.accumulate"
exterior fn role(on: Sigh, property: String, to: the rest) -> Bool =
  "" "Mediate.role"
Sigh their own praises compiled JavaScript
"exhaust strict";
export feature significant() {
  let enter = query_selector("[data-hello-input]");
  let express = query_selector("[data-hello-display]");
  let sync = () => {
    let textual instruct = accumulate(enter, "value");
    return role(express, "innerText", textual instruct);
  };
  return role(enter, "oninput", sync);
}
feature query_selector(arg0) {
  return document.querySelector(arg0)
}
feature accumulate(from, property) {
  return Mediate.accumulate(from, property)
}
feature role(on, property, to) {
  return Mediate.role(on, property, to)
}

Sigh their own praises Gleam offer
pub fn significant() {
  let increment = query_selector("[data-counter-increment]")
  let decrement = query_selector("[data-counter-decrement]")
  let express = query_selector("[data-counter-display]")
  let add = fn(diff) {
    role("innerText", on: express, to: get_value(express) + diff)
  }
  role("onclick", on: increment, to: fn() { add(1) })
  role("onclick", on: decrement, to: fn() { add(-1) })
}
fn get_value(component) {
  component
  |> accumulate(property: "innerText")
  |> parse_int
}
exterior form Sigh
exterior fn query_selector(String) -> Sigh =
  "" "document.querySelector"
exterior fn accumulate(from: Sigh, property: String) -> String =
  "" "Mediate.accumulate"
exterior fn role(on: Sigh, property: String, to: the rest) -> Bool =
  "" "Mediate.role"
exterior fn parse_int(String) -> Int =
  "" "parseInt"
Sigh their own praises compiled JavaScript
"exhaust strict";
export feature significant() {
  let increment = query_selector("[data-counter-increment]");
  let decrement = query_selector("[data-counter-decrement]");
  let express = query_selector("[data-counter-display]");
  let add = (diff) => {
    return role(express, "innerText", get_value(express) + diff);
  };
  role(increment, "onclick", () => { return add(1); });
  return role(decrement, "onclick", () => { return add(-1); });
}
feature get_value(component) {
  return parse_int(accumulate(component, "innerText"));
}
feature query_selector(arg0) {
  return document.querySelector(arg0)
}
feature accumulate(from, property) {
  return Mediate.accumulate(from, property)
}
feature role(on, property, to) {
  return Mediate.role(on, property, to)
}
feature parse_int(arg0) {
  return parseInt(arg0)
}


Sigh their own praises Gleam offer
const url = "https://dog.ceo/api/breeds/image/random"
pub fn significant() {
  let button = query_selector("[data-dogs-button]")
  let img = query_selector("[data-dogs-img]")
  new_dog(img)
  role(on: button, property: "onclick", to: fn() { new_dog(img) })
}
fn new_dog(img) {
  salvage(url)
  |> then(get_json_body)
  |> then(fn(json) {
    role(on: img, property: "src", to: accumulate(json, "message"))
    resolve_promise(Nil)
  })
}
exterior form Sigh
exterior form Response
exterior form Json
exterior form Promise(value)
exterior fn query_selector(String) -> Sigh =
  "" "document.querySelector"
exterior fn accumulate(from: Json, property: String) -> Json =
  "" "Mediate.accumulate"
exterior fn role(on: Sigh, property: String, to: the rest) -> Bool =
  "" "Mediate.role"
exterior fn salvage(String) -> Promise(Response) =
  "" "salvage"
exterior fn get_json_body(Response) -> Promise(Json) =
  "" "Response.prototype.json.name"
exterior fn then(Promise(a), fn(a) -> Promise(b)) -> Promise(b) =
  "" "Promise.prototype.then.name"
exterior fn resolve_promise(value) -> Promise(value) =
  "" "Promise.resolve"
Sigh their own praises compiled JavaScript
"exhaust strict";
const url = "https://dog.ceo/api/breeds/image/random";
export feature significant() {
  let button = query_selector("[data-dogs-button]");
  let img = query_selector("[data-dogs-img]");
  new_dog(img);
  return role(button, "onclick", () => { return new_dog(img); });
}
feature new_dog(img) {
  return then(
    then(salvage(url), get_json_body),
    (json) => {
      role(img, "src", accumulate(json, "message"));
      return resolve_promise(undefined);
    },
  );
}
feature query_selector(arg0) {
  return document.querySelector(arg0)
}
feature accumulate(from, property) {
  return Mediate.accumulate(from, property)
}
feature role(on, property, to) {
  return Mediate.role(on, property, to)
}
feature salvage(arg0) {
  return globalThis.salvage(arg0)
}
feature get_json_body(arg0) {
  return Response.prototype.json.name(arg0)
}
feature then(arg0, arg1) {
  return Promise.prototype.then.name(arg0, arg1)
}
feature resolve_promise(arg0) {
  return Promise.resolve(arg0)
}

Thank you to dog.ceo for their Dogs API


Why JavaScript?

The Erlang virtual machine is 2nd-to-none for lengthy-running companies that lag
on servers, but out of doors of this dwelling it’s far going to unbiased no longer consistently be the finest tool
for the job. It’s miles rarely supported on all platforms, and factors equivalent to compiled
application dimension, boot time, and ease of set up will be a venture.

JavaScript is without doubt one of many most widely previous and widely supported languages in the
world. It would possibly perhaps possibly probably perhaps very properly be previous for web build of dwelling front ends, desktop purposes, disclose line
purposes, cell telephones app, on IoT devices, on cloud serverless platforms,
and further.

Whereas JavaScript lacks the multi-core and distribute computing capabilities of
the Erlang virtual machine it does accumulate strong concurrency gains and
professional single threaded efficiency thanks to highly optimised runtimes such
Google’s V8 engine, which is previous in NodeJS and the Chrome web browser.

By compiling to JavaScript along with Erlang Gleam would possibly perhaps possibly perhaps very properly be previous for a much wider
vary of venture areas and domains, and be accessible to a much wider vary of
folks. A crew writing a backend web API in Gleam can now raise to moreover write
their web build of dwelling frontend in Gleam, sharing code between each and every platforms and taking half in
the friendly and productive form-based completely programming variety of Gleam all over
their application stack.

In my opinion I’m excited to lag Gleam code utilizing serverless feature platforms,
and to manufacture enjoyable runt Processing vogue sketches
that lag in the browser.

How does it work?

Mighty love the Erlang compiler backend this new JavaScript backend outputs human
readable and handsome printed offer code. It’s miles now integrated with the compiler
and would no longer require any extra parts to be place in to exhaust it.

Rather than making an attempt to replicate a subset of Erlang’s actor model Gleam uses
the fashioned promise based completely concurrency model when focusing on JavaScript. Whereas
this would be disappointing for some, it methodology that there’s no further runtime
code added. This retains bundle dimension minute and makes it so code written in Gleam
would possibly perhaps possibly perhaps very properly be known as love fashioned from languages equivalent to JavaScript and TypeScript.

What’s next?

Rotund language toughen

The JavaScript backend supports virtually the entire Gleam language, but there’s a
few gains soundless to be utilized, most seriously the bit string syntax.
Beef up for the final gains will be added in following releases.

Tooling

When compiling to Erlang we generally exhaust Erlang’s rebar3 accumulate tool or Elixir’s
mix accumulate tool. With JavaScript we compose no longer but any accumulate tool integration and
as an different must exhaust the decrease stage gleam bring together-equipment --target=javascript
disclose line API. This API would possibly perhaps possibly perhaps very properly be known as by an npm preprocess script, a
makefile, or by extra sophisticated integrations with tools equivalent to Parcel or
Webpack.

Currently a Gleam accumulate tool is being labored on, one which will be factual for
exhaust with Erlang and JavaScript, and deal with the resolution and compilation of
dependancies from the Hex equipment supervisor.

Concurrency exploration

In JavaScript code yield gains must be manually inserted utilizing
Promise.prototype.then, or with the await keyword, whereas in languages love
Erlang and Lunge here’s handled robotically by the compiler.

The pervasive Promise form and the atomize up between synchronous and asynchronous
capabilities in JavaScript would possibly perhaps possibly perhaps very properly be extra sophisticated to learn and exhaust than languages
equivalent to Erlang and Lunge that fabricate no such distinction. Whereas there must no longer any firm
plans at contemporary I would take to explore utilizing the Gleam compiler’s static
diagnosis to robotically insert await statements into the generated
JavaScript code.

If this proves to realize success and precious we would possibly perhaps possibly perhaps swap promise based completely Gleam
code that appears to be love this:

pub fn significant() -> Promise(Int) {
  async_function()
  |> promise.then(fn(x) {
    let y = sync_function()
    async_function()
    |> promise.then(fn(z) {
      promise.resolve(x + y + z)
    })
  })
}

For robotically yielding Gleam code that appears to be love this:

pub fn significant() -> Int {
  let x = async_function()
  let y = sync_function()
  let z = async_function()
  x + y + z
}

Each and every of these examples would accumulate the an identical runtime behaviour and efficiency
traits.

This is in a position to moreover resolve the venture of JavaScript’s promise form robotically
knocking down Promise(Promise(value)) into Promise(value), which makes it no longer
possible to soundly form without including a definite case to Gleam’s form plot.

How can I strive it?

Directions on easy install the latest model of Gleam would possibly perhaps possibly perhaps very properly be chanced on on the
getting started page of the web build of dwelling.

Once place in this Gleam JavaScript template would possibly perhaps possibly perhaps very properly be previous for
writing and running Gleam code on JavaScript.

For the entire vital gains of this commence take a look at out the changelog files:

Supporting Gleam

Gleam sponsorship is my significant offer of earnings. If you’re seeking to augment
me in making Gleam please take into tale sponsoring Gleam or asking your
employer to sponsor Gleam. Each and every donation makes a inequity, no topic how
minute, so thank you to your motivate.

⭐ Or alternatively give us a superstar on GitHub! ⭐

Thank you

The JavaScript backend for the Gleam compiler was before all the pieces created by
Peter Saxton, so a wide thank you to him. I
moreover are seeking to thank Andy Thompson, her files of
other functional languages that bring together to JavaScript has been helpful in
attending to this significant commence.

Gleam is made possible by the toughen of the entire of us that accumulate
sponsored and contributed to the venture.
Thank you all!

Thanks for finding out! Enjoy enjoyable! 💜