Blog post I saw on Lobste.rs which has a slightly different perpective.
This was a great read, thank you for sharing
As someone who likes and uses functional programming languages, I concur.
Something I’ve noticed is that when I was writing Go, I always missed Error and Result monads. I don’t really miss them in Zig.
Great read, thank for sharing! Comptime is powerful and the reason I recently started using Zig for porting a project from Nim. I’ve been very happy with Nim, but the project hit a stage where I wanted to evaluate other options. I’m doing a fair bit of compile time code and the ergonomics of populating data structures like pre-computing dispatch tables is just a lot easier to do with comptime. Nim can do it, but so far I like working in standard Zig directly vs at the AST level in Nim. I also think it’ll be less brittle in the long run.
I’ve got a lot more to learn about Zig and this article has given me some ideas for experimenting with. ![]()
Ironically it’s Andrew who corrected you on that It’s not a reader monad.
But yeah, Zig is a great language, could use slightly better ergonomics. But besides that I think it’s exactly what we need
…but it is, or at least it’s as near as damn-it. It may not have been designed to be, but the end result is basically the same.
Reader is just a bunch of read-only state which is passed from function to function. You’ll have unknowingly implemented it hundreds of times, I’m sure. In this case the read-only state is the function pointers to implementations of I/O functions[1]. As functions are values in Haskel, having a Reader containing functions is a very familiar pattern to them. It’s how they would do dependency injection once you have anything more complex than a single function. Saying “it’s the reader monad” is just a shorthand way for people familiar with that concept to communicate the idea.
Just the same as when you implement a linked list you wouldn’t say you’ve implemented a List monad, but a Haskeller would say you have.
Ok, strictly speaking, it’s
Statebecause of the buffer that’s both read and written and so you need the more generic form.
↩︎
if you said you implemented a List monad without ensuring the monadic laws hold and without implementing the Monad typeclass, you would be taking a hypothesis for a fact.