Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> Consider a function that is async and throws an error. Is this [x] or [y]?

Is it not that one of these is "an async function that may throw an error immediately" and one "an async function that may throw an error asynchronously"?



This wasn't the best example, as async is directly tied to execution order. But consider a function that is nondeterministic, does IO, and may raise an exception. Is this a:

    Ndet<Io<Exn<T>>>
    Ndet<Exn<Io<T>>>
    Io<Ndet<Exn<T>>>
    Io<Exn<Ndet<T>>>
    Exn<Ndet<Io<T>>>
    Exn<Io<Ndet<T>>>
There isn't really a good general answer. Most languages sweep this under the rug in sone way or other: 'Io, and Ndet, and Exn can be done at any point' or 'just use hidden mutable state' are common.

By using effect sets, we can extract fine-grained over the effects in a program at a given point, without having to worry how effects are assembled and dispatched (indeed, in effect-based languages, most of these effects can be statically inferred).

Most functional languages do model these effects using monads, and provide powerful transformations to ensure that the ordering of encapsulation doesn't matter. The composition is explicit, but at least it's a lot easier than languages that don't support monads.

Writing a language is as much about choosing limitations as it is features. Going from the untyped to the typed lambda calculus limits the number of programs that can be expressed (at least until dependent types get involved), but makes it easier to reason about the remaining set of programs. Monads are more powerful, but harder to reason about. A language without monads that doesn't compromise on an effect system is a pretty great language in my book.


Fair enough, thanks for explaining.




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: