Comment by benreesman

Comment by benreesman a day ago

5 replies

I'll let a real category theorist get into the details that I'll likely flub, but the IO monad is where you end up if you start on this path. That context can be implicit, but it's there, and if you want any help from the compiler (to, for example, guide Claude Code towards useful outcomes) you've got to reify it as a real thing in the formality of the system.

Async and coroutines are the graveyard of dreams for systems programming languages, and Andrew by independently rediscovering the IO monad and getting it right? Hope of a generation.

Functions in the real world have colors: you can have predictable rules for moving between colors, or you can wing it and get C++ co_await and tokio and please kill me.

This is The Way.

throwawaymaths a day ago

it's not a monad, since you can do unholy (for fp) things with it, like stash it in a struct and pass the struct around (even to functions which have no clue theres an io call) or just grab a globalized io object and use that at will arbitrarily at many entrypoints in your function.

most importantly, besides the obvious situations (creating the io object, binding it to another object), it's not generally going to be returned from a function as part of its value.

  • cynicalkane a day ago

    When I write in Haskell, I find myself mentally glossing the returned monadic state, along the lines of, "Oh, an M x is just an x that does monady stuff to get the x". This becomes natural once you get the hang of do-notation and sometimes monad combinators. So I'm not really thinking about the monadic state in the return value a lot.

    It's not really any less natural than thinking stateful programming, except now the state is a reified thing, which I think is strictly advantageous once you get used to it.

  • benreesman a day ago

    i'm relatively confident that andrew will happily break the language again (god love him for that) when it becomes clear that you really want that algebra.

    though i will say, for a systems language, it's probably better to invert the lift/unlift relationship, default to do-notation and explicitly unlift into pure functions. that's almost what const meant in C++ to begin with but it lost it's way.

    • Measter a day ago

      The same Andrew who rejected even basic interfaces in favour of duck-typed generics or manually written vtables?

    • throwawaymaths a day ago

      you're just spreading FUD about zig breaking before 1.0. there is zero basis for you to be "relatively confident" about this matter, because

      1. the io situation is basically restructuring analgously to the allocator situation, which is at this point battle tested. there are currently no "monads wrapping statefulness" anywhere in zig.

      2. It's not in zig's nature to build something because it it satisifies an fp idiom. the abstractions and resulting "thing that the hardware does" (at least in release builds) are generally more or less obvious. the levels of compiler reinterpretation to achieve functional purity are not really the sort of thing that zig does. for example, zig does not have a privileged "iterator" method that the compiler reinterprets in a way that unrolls blocks or lambdas into loops without crossing a frame boundary.