
Gleam: A statically typed language for the Erlang VM - andrenth
https://gleam.run/
======
qchris
As someone familiar with Rust who has been interested in Erlang/Elixir, but
hasn't taken the plunge, this could offer an really nice compromise for
helping to learn without necessarily needing to start from scratch. It
definitely seems worth keeping an eye on!

Also, as an aside, I have to say that I'm a big fan of the proliferation of
educational documentation written using the mdbook format. Since the compiler
is written in Rust, I'd imagine that's where the author drew some inspiration
from (much of Rust's documentation is written using that same format). It's
easy to navigate, the code blocks render nicely, and I generally just find it
pleasant to read.

~~~
lpil
Thank you for the kind words! I hope in future we will fit that niche nicely
:)

------
lelf
See also:
[https://github.com/purerl/purerl](https://github.com/purerl/purerl), an
Erlang backend for PureScript, which is a lot more mature but unfortunately
doesn't get the attention it deserves.

~~~
adelarsq
Nice. Didn't know. Which tools are better to work with this?

~~~
lpil
What do you mean by tools? :)

------
msie
Wow! So far this looks like the language I wanted to make! I wanted something
like Elixir but with type declarations being part of the language as opposed
to being annotations. I’ll be looking at this all weekend! It’s got the right
ergonomics.

~~~
anarchyrucks
You might want to check Inko[0] out. It is still in alpha stage of development
so you can probably contribute to it as well.

Inko is a gradually typed, OOP language which uses erlang like isolated
processes that don't share memory for concurrency.

------
mstade
Looks interesting and quite approachable for someone familiar with C-style
syntax. I was looking through the language tour and it's nice and succinct. A
few things that came to mind:

1\. Can multiline strings be indented, with the indentation stripped out?

2\. Why do floats have their own operators?

3\. What's the rationale for lists and tuples being different, and not just
allowing lists to include different types?

4\. How are module paths resolved?

5\. Pattern matching looks great!

6\. Function argument labeling looks great, I wish all languages did this!

7\. Type system looks simple but capable, but in the User example it looks
like the LoggedIn constructor isn't namespaced to User, so what happens if
another type has the same constructor name? Conflict? On the same note, can
you extend custom types after declaration, by adding constructors? (A little
like Clojure protocols)

8\. Can functions be overloaded, so you can provide multiple implementations
for different argument signatures?

9\. Can you implement custom operators, so you can for example `+` custom
types together?

Looks like a really nice language and I'm looking forward to trying it, but
like others have mentioned I too miss the concurrency aspects given it's built
on Erlang. Big kudos for including interop details in the docs right off the
bat though, this is a big plus in the feature basket!

Great work, definitely going to follow this!

~~~
ivanbakel
>What's the rationale for lists and tuples being different, and not just
allowing lists to include different types?

Heterogeneous lists are a pretty advanced feature in the world of static
typing. Since hetlists normally have to be fixed size anyways to do type-safe
indexing, tuples are good enough for something like 99% of use cases.

~~~
AlchemistCamp
In Erlang, lists are _linked lists_. The fact that tuples are stored in memory
sequentially is a major difference from lists.

~~~
lpil
What data structure would you think of when you hear just "list"?

~~~
qppo
List is an access pattern, like a queue or deque. Linked lists are a data
representation using a couple of pointers.

It's like the difference between a graph and an adjacency list or matrix. A
list being a linked list is an implementation detail.

At least to me. Mostly because linked lists are in general, awful ways to
store data.

~~~
lpil
It depends on what you want to do with them. They have constant time
prepending and support structural sharing, both highly desirable features in
many use cases.

------
virtualwhys
Not an Erlang user, but I must say the syntax is beautiful.

I know, semantics before syntax, but if you can have both, why not?

Looks promising, love the ML-style pattern matching in particular, so clean
and terse (wish Scala 3 would ditch the `case` keyword in match statements,
but alas not happening)

~~~
lpil
Thank you! I'm glad you like the syntax!

------
salimmadjd
Looks interesting. I only wish it used Haskell's type annotation. I've been
learning Haskell recently and I'm really liking how easy it is to read and
digest codes.

I feel like Haskell in general is yielding much cleaner code and once you
start learning it, so much easier to follow the logic of a code and not get
lost in all the noodles of commas, parentheses and unneeded brackets.

~~~
lpil
Hi! I'm the author of Gleam!

Originally Gleam had a more Haskell-like (or rather a more OCaml-like) syntax.
Over time people generally expressed a preference for a more familiar C-like
syntax, citing the unfamiliar syntax making it seem unapproachable.

Originally I thought these thoughts on syntax were unimportant (after all,
syntax doesn't really matter) but after looking at the success of ReasonML (an
alternative syntax for OCaml) and how it brought FP to a much wider audience,
I decided that it would make sense to use this more C style syntax.

Gleam aims to be very accessible and welcoming to as many people as possible,
so in this area we've gone for something I personally prefer less as it it may
help others more.

~~~
willtim
Martin Odersky followed the same logic with Scala and he has since expressed
some regret, especially as more and more people become familiar with Python,
which is more succinct:

[https://github.com/lampepfl/dotty/issues/2491](https://github.com/lampepfl/dotty/issues/2491)

~~~
lpil
I remember that post, interesting stuff! :) I'm hoping to be more concise than
Scala and Java, and to have a much simpler grammar. It is a tricky
middleground to reach

------
epelesis
The guy [1] who runs this project is super nice, about a year ago I was
working on my own Rust based VM and he dropped in with a couple of helpful
tips and ideas.

[1]: [https://github.com/lpil](https://github.com/lpil)

~~~
adamcharnock
I can absolutely confirm this. A wonderful combination of patient, kind, and
super-knowledgeable. He was a very good sounding board in the early days of
one of my projects.

~~~
lpil
Thank you Adam! <3

------
eterm
A little while ago I saw a conference talk about gleam. [1]

It was my favourite talk of the conference outside the keynotes.

The first ten minutes is a good high level introduction to erlang itself.

I've been meaning to check gleam out since, this HN post has served as a good
reminder to do so.

[1] [https://www.youtube.com/watch?v=HaKR2kt-
DXI](https://www.youtube.com/watch?v=HaKR2kt-DXI)

~~~
lpil
Thank you so much! I was pretty nervous seeing as Code Mesh is my favourite
coherence. I'm really glad you enjoyed it :)

------
carlmr
Amazing. Adding the ability to do type driven design on top of the fault
tolerance features of Erlang will make it easier to create correct AND fault
tolerant applications.

Let it fail, but not when you already know at compile time that it's wrong.

------
dang
A related article from last year: [https://notamonadtutorial.com/an-interview-
with-the-creator-...](https://notamonadtutorial.com/an-interview-with-the-
creator-of-gleam-an-ml-like-language-for-the-erlang-vm-with-a-
compiler-e94775f60dc7)

via
[https://news.ycombinator.com/item?id=19547418](https://news.ycombinator.com/item?id=19547418)
(but no comments there)

------
mshockwave
A little disappoint that it doesn't have message passing, one of the most
powerful weapons of the Erlang family. But the language looks clean and neat.
I can understand it within couple of minutes

~~~
macintux
People have been trying for, IIRC, 15+ years to add a full-fledged type system
to Erlang, and the distributed nature keeps defeating them. This problem may
never be solved.

~~~
virtualwhys
See Akka Typed (based on the Actor model) for an example of typed message
passing in a distributed system.

Not sure what compromises were made, but it was a sore point for users of the
library for years to throw around untyped messages when the host language
(Scala) provided such a powerful type system.

~~~
lpil
Akka Typed is not capable of expressing everything Erlang's OTP commonly does
I'm afraid, so it's not a complete solution here.

We do however have typed message passing libraries in Gleam that are in part
inspired by Akka Typed.

------
HorkHunter
I'm really happy the Erlang and BEAM are finally getting the attention /
traction they deserve!

the language was kind of underappreciated or considered very niche for a long
time

~~~
macintux
I came to Erlang (and HN) after this time period, but apparently there was a
period during which the language appeared on the HN front page a ridiculous
amount, sometime around 2010 perhaps?

With the rise of Elixir it’s been getting a fairly steady stream of mentions
here.

~~~
HorkHunter
I'm starting to see the recent interest as well, which I just wanted to
complement.

I've made myself familiar with Erlang around 2011/2012? encouraged by the
writing this amazing book [1]. which is still around and super amazing fast
introduction IMHO. unfortunately I have never implemented anything of
significance with it. maybe its time :)

[1]: [https://learnyousomeerlang.com](https://learnyousomeerlang.com)

~~~
lpil
This is the book I learnt Erlang with! If it didn't exist Gleam probably
wouldn't either.

------
eggy
I'm interested in Erlang, since I first heard about it when I wanted to write
plugins or work on the Wings3D program back in 2003 or 2004. I chose playing
with LFE over Elixir, because I prefer Lisp syntax to Ruby-like syntax, but
limitations of the BEAM, and core have some gotchas for running a Lisp. I'd
like to try Gleam. It looks clean, and I like the fact that it is typed. The
Erlang/OTP and other BEAM languages work well for what they are intended for,
but if you do any number crunching they are slow. The Elixir/Phoenix stack
seems to be a great combo for web developers. I'll give it a try by compiling
it on my Windows box with Rust, since my iMac Pro 27 is mid-2011, and my Linux
notebook is busy right now for other jobs.

~~~
dnautics
> The Elixir/Phoenix stack seems to be a great combo for web developers.

It's a great combo for more than that. I'm building a vm orchestrator on top
of it and couldn't be happier (does everything from DHCP serving to
virtualization library binding and resource matching). I do happen to have
Phoenix in there, but it's for an entirely optional operator dashboard.

~~~
eggy
Is Phoenix only for the optional operator dashboard? I ask because I have not
tried Phoenix. I've played with Elixir since it came out, but only Elixir.

~~~
dnautics
yep, although I am working on rewriting the user frontend in Phoenix, that is
a political hurdle to get out into the wild. Most people learn Phoenix, then
elixir, but I also learned Elixir, then Phoenix, and I think it gives me a
stronger handle on how the VM works under the hood.

------
MrLeap
Forgive me, I'm ignorant -- what's erlang for. "Concurrent applications" is
the raison d'etre I see espoused. What's that mean?

Does it make concurrent applications easier to write? Does it make it easier
to use the SIMD instruction set, how hard is it to get a function written in
erlang to run on a gpu?

Is it like nodejs but more performant? I appreciate anyone who has answers
here, I try to position all the relatively interesting things I don't have
much time to dive in to in a mental model with opportunities for future
promotion.

~~~
derefr
> What's that mean?

"Concurrent applications" as in the C10M problem
([http://c10m.robertgraham.com/p/manifesto.html](http://c10m.robertgraham.com/p/manifesto.html)):
servers serving a lot of clients at once; usually with the added assumption of
a diverse request workload (i.e. some requests are IO-bound, some are CPU-
bound, some are long, some are short, etc.)

• WhatsApp used Erlang (on FreeBSD) to scale 50 engineers and ~1000 boxes to
handling billions of chat-message transactions per second.
([https://www.infoq.com/presentations/whatsapp-
scalability/](https://www.infoq.com/presentations/whatsapp-scalability/))

• A lot of modern financial infrastructure (banks, exchanges, etc.) is built
on Erlang. If there's a financial system that can get away with not being
_hard_ -real-time, chances are someone's considered writing it in Erlang.

• Many massively-multiplayer games have Erlang in their backends or their
networking middleware.

• And, of course, the original point of Erlang was to route (millions of
concurrent) calls in Ericsson backbone telecom routers. It can be deduced from
Ericsson's continued work on Erlang's "megaco" H.248 application, that they're
using Erlang in their LTE IPMS gateway appliances, to route cell-subscribers'
VoLTE audio- and video-call frames.

> Is it like nodejs but more performant?

Node.js is decidedly bad at this type of concurrency (although its libuv _is_
used successfully in software like Nginx—it is rather Javascript's thread-
isolation semantics that bottlenecks Node.js code, not V8 as a runtime.) A
better comparison is with Golang. If you put Node and Golang on a spectrum of
"ability to handle highly-concurrent heterogenous workloads", then Erlang is a
point much further along that spectrum than either of them.

(Golang gets pretty far if the workload is _homogenous_ , though. And you can
get even further still on that spectrum with custom C or JVM code; but in the
process, you'll likely sacrifice either 99th-percentile latency, or lock
yourself into coding in terms of state machines. Erlang sits an an optimum
where you can just write blocking code in actors and it does the right thing,
predictably, even when you have millions of actors.)

~~~
jeremyw
Can you say more about Go and homogeneous workloads? You might be referring to
mixed IO- & CPU-bound tasks, and Go's former inability to preemptively
schedule tightly written loops? (Solved along the way:
[https://github.com/golang/go/issues/10958](https://github.com/golang/go/issues/10958))

Or something else?

~~~
derefr
Nah, just talking about the fact that Go doesn't scale well to using _millions
of channels_ to talk to _millions of goroutines_ , each one executing as part
of a small goroutine-cluster running independent functionality with its own
requirements for data-architecture.

Imagine you took all the AWS Lambda functions of all the different Lambda
users, compiled them together into one binary, and then ran that single binary
on one huge vertically-scaled server, allowing all the Lambda tenants to hit
that server to run requests against their own workloads in the address-space
of that single binary. That's a clear "heterogenous workload": one where
you've spawned a bunch of green-threads within your process, and those green-
threads are all trying to do _different things._ It's a million little job-
shops under one roof (with, importantly, only one "door" in and out, that
everyone has to coordinate to share); rather than one big factory where a
million workers each have a defined job and there's a big loading bay that is
declared from the top to be exclusively owned-and-operated by one department.

Erlang handles the "million job-shops under one roof" use-case pretty well.
Golang kinda-sorta handles it, but kinda falls over, too, because the Golang
runtime (and the whole concept of reifying typed channels as objects) isn't
tuned for the case where each task has spawned an ephemeral digraph of
communication paths between ephemeral actors. Channels have a Golang-runtime-
system overhead just for existing, a bit like processes or sockets do for the
OS. So, like processes or sockets, you're not supposed to just create a
channel for each little thing until you've got a million laying about; you're
supposed to reuse or share them (and the goroutines they address) between
multiple workloads.

Idiomatic Golang code is written in a more dataflow-y pipeline-y SIMD-y way
(the "factory with a million workers" above), where you've got static "actors"
sending massive amounts of work between them, perhaps tagged with the request
they're "about." When this is the 'data architecture' of your code, the Golang
runtime can actually beat BEAM (using an equivalent architecyural abstraction,
e.g. [https://hexdocs.pm/flow/Flow.html](https://hexdocs.pm/flow/Flow.html))
in _both_ throughput and latency, since it's exactly what the Golang runtime
has been tuned for.

The downside of the dataflow approach is that, compared to actors-as-little-
Turing-machines, dataflow is a very hard data-architecture to reason about!
(And also tends to mean that a logic error in any of your static dataflow
worker-actors, causes a lot of "collateral damage" when it comes down, to the
point that it often may as well bring down the whole system with it. A stall
in an assembly line stops the whole factory; but a stall in a job-shop doesn't
stop the whole economy!)

------
akst
Nice! I’d imagine this is a much nicer experience than dialyzer.

If the author is reading is it possible to type message passing / processes? I
couldn’t see this in the docs but i may have missed it

~~~
lpil
It's not supported in the core language but we have some type safe bindings to
messages and message passing as libraries. We may upgrade these to being part
of the language itself but I don't want to rush this and get stuck with a sub-
optimal design.

~~~
mtarnovan
This is a very interesting project, thanks. I'd love to see how you solve the
problem of typed message passing in the language itself.

~~~
lpil
These two libraries are probably the best to look at:

[https://github.com/gleam-experiments/otp_agent](https://github.com/gleam-
experiments/otp_agent) [https://github.com/gleam-
experiments/otp_process](https://github.com/gleam-experiments/otp_process)

They could be improved but they are good enough for us to get started with.

------
aabbcc1241
Not sure about IDE integration but the language looks nice. Having a typed
language makes me reconsider using the beam in my next project !

~~~
lpil
LSP support is on the backlog. Having world class IDR features in all editors
is an important part of the puzzle in my opinion.

------
ProfHewitt
For those interested in the underlying theory of Actors see the following:

    
    
        Information Security Requires Strongly-Typed Actors and Theories
           https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3418003
        Physical Indeterminacy in Digital Computation
            https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3459566

------
Karupan
Dumb question from a non Erlang person - can this be used along with Elixir?
I’m looking at Phoenix LiveView but would love to use Gleam for core
functionality. Is this anything like Scala/Clojure and compiles down to
Erlang, I’m guessing that is possible?

~~~
lpil
Yes, it can be used with Elixir. We don't yet have any integration with mix
(the Elixir build tool) so if I were to use both in the same project I would
probably create an umbrella style application with one Elixir application and
one Gleam application within it.

~~~
lpil
Also, I don't think that's a dumb question! Gleam does compile to Erlang, yes.

------
rajeshrajappan
lpil is super smart and generally an awesome guy. I worked with him at a
startup and learned a lot from him.

~~~
lpil
Thank you Raj, you're pretty great yourself!

------
cinnamonheart
This is really neat! Have you considered an ML-like module system, with
functors and such? I'd be curious if they could be connected with Erlang's
processes somehow :)

~~~
lpil
At present we do not have a module + functor system as it does not mesh well
with the compilation model of Erlang.

I am interested in having a feature like this but there is much work and
research to be done first.

------
zerr
Any plans for self-hosting?

~~~
lpil
Not at present, though it would be nice to be able to do that one day.

It would be largely a vanity project so I don't intend to spend time on it
when we could be building more useful things.

------
1propionyl
Is it just me or does the introduction not mention equivalents to Erlang's
messaging operators, or how to use OTP at all? Or _anything_ about proceses
_at all_!?

I feel like this is Rust syntax on top of beam... but seems to be missing the
point of Erlang.

~~~
lpil
The website current is an introduction to just the language itself. Later we
have detailed documentation on the subject of OTP, but there is a lot of work
to do first. Gleam is a very young language.

As a keen Erlang programmer I assure you that Gleam will do its best to make
full use of the runtime's fantastic properties :)

------
VWWHFSfQ
This looks _very_ interesting.

Saved.

