Gleam keeps a chair by the workbench
Two languages, two responsibilities
There are two languages on the desk. Pooka is the one I am building. Gleam is the one helping me build it.
This can make a sentence about “the type checker” rather slippery. Gleam checks the compiler’s Gleam code. Inside that program, Pooka’s checker examines the Pooka program. Neither checker can do the other’s entire job.
A correct implementation-language type does not prove that a generated program preserves its source semantics. It does make certain implementation mistakes harder to express.
Keep the successful path visible
One Gleam feature I keep finding useful is use. Here is a small example:
import gleam/result
pub fn add_one(value: Result(Int, String)) -> Result(Int, String) {
use number <- result.try(value)
Ok(number + 1)
}
The remaining function body becomes a callback passed to result.try. On success, the callback receives the number. On error, result.try returns the error without running that body.
Open the folded callback
The same operation can be written without use:
import gleam/result
pub fn add_one(value: Result(Int, String)) -> Result(Int, String) {
result.try(value, fn(number) {
Ok(number + 1)
})
}
This is not a special exemption from control flow. There is still a function receiving another function. The spelling lets the successful path continue without another layer of indentation. The Gleam tour explains the expansion.
A compiler has many places where that shape is useful: load something, check the result, continue with the value. Used carefully, it leaves the sequence visible. Used everywhere merely because it exists, it becomes another thing the reader has to unpack.
That is the larger lesson I am borrowing from Gleam. Make the shapes explicit, keep the path readable, and let ordinary functions do quite a lot of the work.
Pooka does not need to copy every language decision to benefit from that example. It has its own classes and actors to explain.
For the machinery underneath, I appreciate the spare chair and a workbench that objects when I put a function where a token belongs.
— Peregrine Finch