Member-only story

A new milestone for Letlang

David Delassus
7 min readMar 13, 2023

--

For the past few months, I have been working on my own programming language, Letlang. You may have already read a bit about it in my previous articles.

I’m happy to announce that one of the biggest feature of the language is now specified, implemented, and working!

But what is that feature?

Effect handlers

In Letlang, you can delegate computations to the caller of the function. Those are called effects.

In order to do this, you first need to declare the effect signature:

class loglevel(lvl: @debug | @info | @warn | @error);
effect log(lvl: loglevel, message: string) -> @ok;

This defines a symbol in the current scope, which can be used with the perform keyword. That keyword indicates that you want to delegate the handling of that effect to the caller:

result := perform log(@debug, "hello");

If the caller does not handle the effect, it is propagated to the caller’s caller, and so on until it has propagated to the Letlang runtime. If the Letlang runtime have a builtin handler for that effect, it will be called, otherwise the process will exit with an error.

Once the handler have been called, its return value is passed to the code which performed the effect, and execution resumes normally.

This part was already implemented, and the std::io::println and std::io::readline functions were actually performing effects already built-in the runtime.

The news here is about custom handlers. The developer can now intercept effects (with pattern matching ❤️):

module example::main;

import std::io;

class loglevel(lvl: @debug | @info | @warn | @error);
effect log(lvl: loglevel, message: string) -> @ok;

pub fn main() -> @ok {
@ok := do {
@ok := perform log(@debug, "a debug message");
@ok := perform log(@info, "hello world");
@ok;
}
intercept log(@debug, _message) {
# silence debug loglevel
@ok;
}
intercept log(_level, message) {
std::io::println(message);
@ok;
};

@ok;
}

The do{} block defines a new scope, and intercept clauses define effect handlers. When an effect is performed within the do{} block, it will use…

--

--

David Delassus
David Delassus

Written by David Delassus

CEO & Co-Founder at Link Society

No responses yet

Write a response