Shout out to Giacomo's twitch streams. He has taught me about some features of Gleam, Rust, and on top of that he's just a very chill person. He takes time away from his focus to answer questions politely and without judgement. There are dozens of programming streams where the streamer forgets to leave their ego at the door and he is not one of them. I highly recommend following it.
The Gleam community is generally very very nice. I maintain about 200k lines of Gleam[0][1], and they have generally have accommodated even my stupidest posts on Discord.
The language itself is as welcoming. Even LLMs are less cranky and output nicer code, not having to deal with React.
to those curious, erlang abstract form[1] is the AST representation used by the erlang compiler/etc. per [1], you can see that it's canonically made of erlang terms, and you have easy access to routines for manipulating this representation from the standard library; it's really comfy when you need it! it's also the target elixir compiles down to, and the representation manipulated by parse transforms, which in base erlang are the way syntactic sugar (notably qlc[2] and some of the more cutesy pattern matches in merl[3] (which, in turn, manipulates the very same representation to do its job. very meta!)) is done.
Before the "and", "but", "so", "while", etc. — while most European languages, indeed, (usually) require commas before conjunctions, English is following a somewhat reversed convention. Well, at least the author remembered that they need to omit a comma before "that".
i dont think anyone actually cares unless you are in english class or someone wants to feel smug on the internet (you can ignore the 2nd one completely).
Informally, commas are "misused" regularly even by native writers, and almost no one notices or cares unless the misuse is frequent and egregious.
Formally, most comma use is an issue of style, not grammar, and style guides differ on when they should and shouldn't be used. The main rule that's actually a matter of grammar is this: commas cannot be used to join two "clauses" (phrases which could be independent sentences) without a conjunction.
English has no central authority, so the lines between grammar and style can get fuzzy. Most guides would say you need an "and" after the second comma, but some make an exception if the clauses are "very short and alike in form". See Wikipedia's article Comma splice if you are interested in the pedantics. https://en.wikipedia.org/wiki/Comma_splice
You still didn't answer: am I supposed to write "I'm eating a hot dog she's listening to radio" without a comma for that sentence to be grammatical? Or am I supposed to always insert "and" into it?
Without a comma, it's a run on sentence, and is ungrammatical. You should join the clauses with a conjunction like "and", and including a comma before the conjunction is a common style.
Joining the two clauses with only a comma — that is, without also using a conjunction like "and" — is typically also considered a run on sentence and ungrammatical.
So it's "You do need a comma before a conjunction, if it connects two independent clauses" then — "you need a comma before a conjunction" and "it connects two independent clauses" are two fully formed simple sentences, each having its own subject and predicate. See what I mean?
And almost nobody writes sentences like "I love her and she loves me back" with a comma before "and".
A subordinating conjunction like if turns an independent clause into a dependent clause, so you don’t use a comma.
> And almost nobody writes sentences like "I love her and she loves me back" with a comma before "and".
In informal writing, people frequently leave out commas for everything but lists.
But it’s also very common to see it used “correctly”. In any kind of writing where someone would be expected to proofread what they wrote, I’d expect it.
The comma prevents readers initially grouping words incorrectly.
“I called John and Mary answered.”
Your brain will start to parse that as “I called John and Mary” before backtracking once you hit the last word.
idk, i'm not sure about wording.
erlang abstract form still is erlang source, it's ast of erlang source text.
one call to erl_prettypr:format and text source is back.
word 'transpiler' is still there and there is nothing "pejorative" in it, it's transpilers all the way down everywhere.
but talking pejorative, i was surprised.
my opinion of gleam was already pretty low, but i did not expect to see post-1.0 compiler emitting text erlang source.
maybe it's not that good of idea to implement compiler in language completely foreign to target ecosystem.
I don't think your "it is source as you can convert it back into source" argument holds water as all the Erlang formats can be decompiled into Erlang source code, including the final bytecode itself.
I think you're overthinking the cost of compiling to source, and also underestimating how common it is.
> all the Erlang formats can be decompiled into Erlang source code
Nope, I'm not buying. This is roughly "any executable binary can be decompiled to C" which is kinda true, but we both know it's not how the real world works.
Compilation is lossy, parsing to AST is almost lossless.
> the cost of compiling to source
But now you paid this cost a second time. To build textual Erlang source programmatically, you need some kind of AST anyway, as I highly doubt you were using direct text templating. So you had an incomplete copy of Erlang Abstract Format, which is THE Erlang AST, but had to write your own pretty-printing.
If I were to implement code generation targeting BEAM in language X I would start with making some tool(in Erlang) to fetch abstract format definition from erl_parse typespecs and make code generator to X emitting matching definitions and ETF serialization code. It is relatively simple, it is unavoidable anyway, and it lets me avoid bothering with textual Erlang puctuation.
I just don't get it. It's not even fun!
Also I'm currently playing with idea of compiling Core Erlang via OCaml backend, there is a mirror problem - parsing of Core into OCaml terms. And no way I'm implementing proper lexing/parsing of Core, I'm going with ETF right from start.
No AST was ever used for that. Printing algebra was used in the past, and the new Erlang binary and textual generators both work by appending to a buffer. Your assertion that we need an AST has never been correct. From my point of view it would be wasteful and slow for the compiler to construct this AST just to then consume it to push bytes to a buffer.
RE punctuation, the book-keeping required for the binary format is no less work than for the textual format. All these formats are similarly easy to implement, though the ones that are not human readable are more challenging to debug.
I use it mostly for web APIs / services, it's great for that!
Interop is not seamless since Elixir does not have the same static type system, but it is possible and that does help sometimes. When resizing images for example, I fall back to Elixir's bindings to libvips. I've also used Oban from Gleam in the past.
JavaScript is useful in lots of places, and even if one compile target is especially good for in-browser user interfaces that doesn't mean that language is specifically intended for user interface development.
This raises an obvious question. Why Gleam team weren't doing that in the first place? Obviously they didn't have direct Gleam AST -> Erlang source pipeline, they must have had to build some their own custom Erlang AST representation that they then translated into the source code.
We did not (and still don't) have an internal Erlang AST representation in the compiler. Previously we did have a Gleam AST -> printing algebra -> Erlang source pipeline, now we construct a buffer of bytes with the data encoded as Erlang Term Format.
Source was the previous target as at the time Erlang Abstract Terms was not established as the go-to format (Core Erlang was more popular but it did not have a stable API outside of the BEAM, so Gleam's in-Rust compiler could not construct it), and due to the newness of the language having an "escape hatch" where one could abandon Gleam and eject to Erlang was highly valuable. It also meant we could use the Erlang build tool until the Gleam one was ready for use.
Gleam is such a beautiful language. I wish I had the opportunity to use it more. If it could compile (transpile) to a native target like rust or go, it would be truly perfect.
Go's garbage collection isn't well suited for an immutable language like Gleam, so the performance would likely be disappointing compared to other targets.
I don't get the impression that javascript is among Gleam's targets because of performance.
- server target: BEAM
- client target: js
Once you've covered those bases, you're kind of done.
If the server needs to do something special in an OS process... might as well let the OS mediate that interaction so that it can be fully generic, rather than trying to bend the language around whatever the unknown action might be.
Never used gala, but it seems going a bit more down the deep end, frankly it has features is dislike / would never use.
Lisette has been pretty straight forward, with its good Go interrop and familiarity (i have ocaml experience). Tooling is GREAT for such a young language. Im also a huge fan of the recent addition of a "zero" value. No nils like you get in vanilla Go.
I tend to write libraries in Lisette i then import in my go "shell", thats more or less a main function with some setup.
Full (lisette->go->lisette) Go interrop is still a WIP, but im certain it will be improved upon soon.
Thank you for the reply! There's very little public discussion (at least that I can find) about people's experiences writing Lisette, the language, or how well agents do with it so far so I really appreciate it. Been debating past couple days if I spend some of my claude sub tokens to try a partial rewrite of some code.
Yeah, i think lisette just needs some time (its pre 1.0, so probably not used in prod), but that said i read Listte is actually already used for building compilers for other languages.
Some people like to live on the bleeding edge, and once again, that said, the Go runtime is just so good so you have a solid base, and can always eject from lisette by just keeping the generated Go source. That makes it a more safe language to choose.
It seems to me like both Gala and Lisette are fairly safe to invest in for small projects that you'd otherwise write Go in assuming you have the token budget and patience to be able to as ask an agent to make the generated Go more idiomatic afterwards / do a native Go rewrite if needed.
I'm still not sure if I would rather test out Gala or Lisette or both, I appreciate hearing you've had a positive experience with Lisette!
Not sure about gala, but lisette produces good and readable go-code. There is a prelude (option, reault etc) package you possible would want to get rid of if you ejected. But an LLM could easily do this manual task for you pretty easily.
What do you mean by native target in this instance? Since you mentioned Rust, which is a systems language that compiles to native with no runtime, and Go, which has a garbage collector and runtime, as examples I'm a little confused.
Gleam is a simple functional programming language which leans into static typing , friendly tooling, and a one-way-to-do-it style. You'd want to use it if you enjoy the programming experience it provides.
It is if you want Erlang but typesafe and with a modern syntax. And why would you want Erlang? Erlang was built for making it easy to build fault-tolerant concurrent applications, for example in telecom.
Erlang is one of those runtimes I've loved since learning about it all the way back in 2008, but I never took time to learn the syntax, but Elixir and Gleam have had me fiddling with the Erlang VM over the years. Happy to see Gleam growing into maturity.
I'd say if you know and like Rust, then Gleam should be easy to pick up but otherwise I'd try Elixir. You can learn most of the language in a few days and be experimenting with BEAM and supervision concepts basically on day one. As a learning exercise I think its worth peoples' time because actors/processes are one of the concurrency models you don't see everywhere but solve interesting problems well.
I just learned Erlang this year and I love the syntax. Ending expressions with periods took getting used to, but capital first letters distinguishing variables, non-rebindable variables, semicolons between function clauses, a lack of boilerplate (defmodule et al), a fraction of end keywords, commas separating expression, ... all make for a very fun to use and ergonomic language, IMO.
I haven't tried Gleam yet, though. I'm interested in the focus on simplicity but a little wary because I understand they sacrificed niceties to minimize the language footprint, e.g., pattern matching in function heads. I intend to give it a shot the next time I'm greenfielding something.
Erlang is my favorite functional language out of all the ones I've tried. The matchers, guards, etc are all done very well. It's just that I don't like functional. I used to think it was cool, gave it a real chance, and eventually decided it's not a good fit for many use cases.
Like at some point the neatness of doing all loops as recursion wears off and it's just tiring. Most code doesn't look like CS algorithms homework.
> Like at some point the neatness of doing all loops as recursion wears off and it's just tiring.
Odd, but I believe you, lol. Elixir's list comprehensions take a `:reduce` option which makes accumulating values a bit more "familiar" and I often use over `reduce`:
for a <- list, reduce: []
acc ->
[a | acc]
end
Not sure if there is something like that in Erlang (or Gleam for that matter).
The title is a bit misleading because one might imply that Gleam no longer compiles to something Erlang can use (not true).
From the article:
> Over the last few months Giacomo Cavalieri has entirely rewritten Gleam's Erlang code generator that has an entirely different design, and most notably, outputs a different format. Previously Gleam generated Erlang source code, now it generates Erlang abstract forms.
> "Transpiler" means a compiler that outputs a human-readable format, such as source code. It's a cool sounding word, but most the time people use it to imply that a given compiler is in some way inferior. This is very silly, as there is nothing about compiling to a human-readable format that makes a compiler easier to implement.
Ok but this footnote comes at the end of a paragraph describing how the previous transpiler implementation was inferior to the new compiler. It's ok to make these distinctions.
The old one had an inferior implementation, but that is unrelated to the output format. We also have a new Erlang source code generator that is used predominantly in the compiler test suite, and it too is superior.
I will just say, as of recently, especially thanks to AI, I've been doing projects in Gleam, I am on third Gleam project and it has been very pleasant experience. It takes longer to write but it is much shorter, easier to follow and much more easier to update and change.
I love this language, but I have to wonder how much harder it is to grow a niche language these days when everyone is just telling Claude what to build for them. It seems like LLM friendliness is going to become the new benchmark for adoption if it hasn't already, and I find that pretty sad.
The people who are just telling Claude to build stuff for them weren't programmers who cared about the craft anyway. It's not very likely they would've ever chosen a niche language, rather than something for which they could easily copy code examples.
98 comments
[ 2.6 ms ] story [ 10.7 ms ] threadThe language itself is as welcoming. Even LLMs are less cranky and output nicer code, not having to deal with React.
[0]: https://blisswriter.app/
[1]: https://nestful.app/
1: https://www.erlang.org/doc/apps/stdlib/erl_parse.html#t:abst...
2: https://www.erlang.org/doc/apps/stdlib/qlc.html#q/2
2: https://www.erlang.org/doc/apps/syntax_tools/merl.html
https://github.com/lfe/lfe/blob/387d0aa1092bdda0ca17481869e8...
https://github.com/lfe/lfe/blob/387d0aa1092bdda0ca17481869e8...
The lack or excess of commas doesn't upset any reasonable person in the slightest.
Formally, most comma use is an issue of style, not grammar, and style guides differ on when they should and shouldn't be used. The main rule that's actually a matter of grammar is this: commas cannot be used to join two "clauses" (phrases which could be independent sentences) without a conjunction.
Joining the two clauses with only a comma — that is, without also using a conjunction like "and" — is typically also considered a run on sentence and ungrammatical.
And almost nobody writes sentences like "I love her and she loves me back" with a comma before "and".
A subordinating conjunction like if turns an independent clause into a dependent clause, so you don’t use a comma.
> And almost nobody writes sentences like "I love her and she loves me back" with a comma before "and".
In informal writing, people frequently leave out commas for everything but lists.
But it’s also very common to see it used “correctly”. In any kind of writing where someone would be expected to proofread what they wrote, I’d expect it.
The comma prevents readers initially grouping words incorrectly.
“I called John and Mary answered.”
Your brain will start to parse that as “I called John and Mary” before backtracking once you hit the last word.
but talking pejorative, i was surprised. my opinion of gleam was already pretty low, but i did not expect to see post-1.0 compiler emitting text erlang source. maybe it's not that good of idea to implement compiler in language completely foreign to target ecosystem.
I think you're overthinking the cost of compiling to source, and also underestimating how common it is.
Nope, I'm not buying. This is roughly "any executable binary can be decompiled to C" which is kinda true, but we both know it's not how the real world works. Compilation is lossy, parsing to AST is almost lossless.
> the cost of compiling to source
But now you paid this cost a second time. To build textual Erlang source programmatically, you need some kind of AST anyway, as I highly doubt you were using direct text templating. So you had an incomplete copy of Erlang Abstract Format, which is THE Erlang AST, but had to write your own pretty-printing.
If I were to implement code generation targeting BEAM in language X I would start with making some tool(in Erlang) to fetch abstract format definition from erl_parse typespecs and make code generator to X emitting matching definitions and ETF serialization code. It is relatively simple, it is unavoidable anyway, and it lets me avoid bothering with textual Erlang puctuation.
I just don't get it. It's not even fun!
Also I'm currently playing with idea of compiling Core Erlang via OCaml backend, there is a mirror problem - parsing of Core into OCaml terms. And no way I'm implementing proper lexing/parsing of Core, I'm going with ETF right from start.
RE punctuation, the book-keeping required for the binary format is no less work than for the textual format. All these formats are similarly easy to implement, though the ones that are not human readable are more challenging to debug.
Interop is not seamless since Elixir does not have the same static type system, but it is possible and that does help sometimes. When resizing images for example, I fall back to Elixir's bindings to libvips. I've also used Oban from Gleam in the past.
Source was the previous target as at the time Erlang Abstract Terms was not established as the go-to format (Core Erlang was more popular but it did not have a stable API outside of the BEAM, so Gleam's in-Rust compiler could not construct it), and due to the newness of the language having an "escape hatch" where one could abandon Gleam and eject to Erlang was highly valuable. It also meant we could use the Erlang build tool until the Gleam one was ready for use.
- server target: BEAM
- client target: js
Once you've covered those bases, you're kind of done.
If the server needs to do something special in an OS process... might as well let the OS mediate that interaction so that it can be fully generic, rather than trying to bend the language around whatever the unknown action might be.
Lisette has been pretty straight forward, with its good Go interrop and familiarity (i have ocaml experience). Tooling is GREAT for such a young language. Im also a huge fan of the recent addition of a "zero" value. No nils like you get in vanilla Go.
I tend to write libraries in Lisette i then import in my go "shell", thats more or less a main function with some setup.
Full (lisette->go->lisette) Go interrop is still a WIP, but im certain it will be improved upon soon.
Some people like to live on the bleeding edge, and once again, that said, the Go runtime is just so good so you have a solid base, and can always eject from lisette by just keeping the generated Go source. That makes it a more safe language to choose.
I'm still not sure if I would rather test out Gala or Lisette or both, I appreciate hearing you've had a positive experience with Lisette!
All I understand from the frontpage is that it's typesafe. Good I guess? Then there is something about Erlang which I never used.
I haven't tried Gleam yet, though. I'm interested in the focus on simplicity but a little wary because I understand they sacrificed niceties to minimize the language footprint, e.g., pattern matching in function heads. I intend to give it a shot the next time I'm greenfielding something.
Like at some point the neatness of doing all loops as recursion wears off and it's just tiring. Most code doesn't look like CS algorithms homework.
Odd, but I believe you, lol. Elixir's list comprehensions take a `:reduce` option which makes accumulating values a bit more "familiar" and I often use over `reduce`:
Not sure if there is something like that in Erlang (or Gleam for that matter).Imagine a doctor about to do surgery and opening a toy box
From the article:
> Over the last few months Giacomo Cavalieri has entirely rewritten Gleam's Erlang code generator that has an entirely different design, and most notably, outputs a different format. Previously Gleam generated Erlang source code, now it generates Erlang abstract forms.
Ok but this footnote comes at the end of a paragraph describing how the previous transpiler implementation was inferior to the new compiler. It's ok to make these distinctions.
I was surprised to find Matt Mullenweg among the sponsors.