Remix.run Logo
rivetfasten 2 hours ago

This looks really nice! I'm excited to see it and am left with questions from perusing the site. Let me know if I missed it.

It's simple and also has an excellent choice of where to invest in powerful features. It looks like an elegant, minimal selection of things existing languages already do well, while cutting out a lot of cruft.

The site also mentions two differentiating and less established features that make it sound like more than yet another fp remix: type-based ownership and algebraic effects.

While ownership stuff is well explored by Rust and a less explicit variation by Mojo, this sounds like a meaningful innovation and deserves a good write-up! Ownership is an execution-centric idea, where fp usually tries to stay evaluation-centric (Turing v Church). It's hard to make these ideas work will together, and real progress is exciting.

I'm less familiar with algebraic effects, but it seems like a somewhat newer (in the broader consciousness) idea with a lot of variation. How does Loon approach it?

These seem like the killer features, and I'd love to see more details.

(The one technical choice I just can't agree with is multi-arity definitions. They make writing code easier and reading it harder, which is rarely or never the better choice. Teams discourage function overloading all the time for this reason.)

Thanks for sharing!

ecto an hour ago | parent [-]

thanks for the kind words :)

You're right, ownership and effects are the real differentiators. The idea here is to let the compiler discover ownership rather than it being declared imperatively

Regarding algebraic effects, Loon uses continuations similar to Koka but more restrictive. Effects are declared with operations, and every side effect (IO, failure, async, state) is an effect that propagates through the call graph. The interesting part is `handle`, which lets you intercept effects:

  [handle [load-config "app.toml"]
    [IO.read-file path] [resume "mock contents"]
    [Fail.fail msg]     "default"]
Handling an effect subtracts it from the function's effect setso a function that handles all its IO internally is pure from the outside. This replaces exceptions, async/await, DI, and mocking with one mechanism. Testing is just handling effects with test data

Multi-arity: get lost! fork me?