Subject: Re: bug#61214: [PATCH guix-artwork] website: posts: Add Dissecting Guix, Part 2: The Store Monad.

From: Ludovic Courtès <[email-masked]>
Date: Sun, 12 Feb 2023 19:05:43 +0100

Hello!

"(" <[email-masked]> skribis:

> * website/posts/dissecting-guix-2-store-monad.md: New blog post.

Nice work again!  Some comments below:

> +In [the last post](https://guix.gnu.org/en/blog/2023/dissecting-guix-part-1-derivations/),
> +we briefly mentioned the `with-store` and `run-with-store` APIs.  Today, we'll
> +be looking at those in further detail, along with the related monad API and the
> +`%store-monad`!

Like Chris, I’m wary of acronyms (they can easily make things
impenetrable) so I’d write:

  - the `with-store` macro and the `run-with-store` procedure
  - the related monad interface

> +Monads are a little hard to explain, and from a distance, they seem more than a
> +bit confusing.  So, I want you to erase monads from your mind for now.  We'll
> +come back to them later.

I agree with Chris’s comment: a few sentences of a higher-level intro
showing where this fits in the big picture would be great!

It would be nice to stress, also, that one doesn’t _need_ to know about
monads to use the various programming interfaces of Guix; instead, it’s
a thing for someone who’d like to get a deep dive into the internals of
Guix.

I’m saying this because we FP people, especially in the Haskell camp,
are sometimes very good at making things look fancy and complicated.
The last thing we’d want is to make it sound like this whole thing
targets an audience of people with a PhD in the field.  :-)

> +# Yes, No, Maybe So
> +
> +Let's instead implement another M of functional programming, _`maybe`_ values,
> +representing a value that may or may not exist.  `maybe` is a very common
                                                  ^
Maybe add something like “For example, one might write a function that
divides two integers such that it returns special value `nothing` when
the divisor is zero, and `maybe 5` when passed `15` and `3`.”  (I
couldn’t think of a better example but you get the idea.  :-))

> +feature of strongly-typed functional languages, and you'll see it all over the

s/strongly/statically/  :-)

> +place in Haskell and OCaml code. However, Guile is dynamically typed, so we
> +usually use ad-hoc `#f`s and `'()`s for null values instead of a proper
> +"optional" value.

In Scheme we use #f, not '(), to denote “Nothing”.

> +# New Wheel, Old Wheel
> +
> +Now that we've reinvented the wheel, we'd better learn to use the original
> +wheel.  Guix provides a generic, high-level monads API, along with the two
> +generic monads `%identity-monad` and `%state-monad`, and the Guix-specific
> +`%store-monad`.  Since `maybe` is not one of them, let's integrate our version
> +into the Guix monad system!
> +
> +First we'll make the API available:

Maybe “First, let’s import that module:”?

> +```scheme
> +(use-modules (guix monads))
> +```
> +
> +To define a monad's API in Guix, we simply use the `define-monad` macro, and

“To define a monad in Guix, we use `define-monad`”

(In general, I’d avoid “simply” because whether it’s “simple” depends on
one’s background.)

> +`bind` is just the procedure that we use to compose monadic procedure calls
> +together, and `return` is the procedure that wraps values in the most basic form
> +of the monad.  A properly implemented `bind` and `return` must follow these
> +laws:

s/these laws/the so-called _monad laws_/

(since you use that term below)

> +;; First law: the left identity.
> +(equal? (maybe-chain (something 0)
> +                     mlaws-proc-1)
> +        (mlaws-proc-1 0))
> +;; #t

Should it be “⇒ #t” instead of “;; #t”, to follow the convention used in
the manual and in other places?

> +What have we learned about monads?  The key points we can take away are:
> +
> +1. Monads are a way of composing together procedures and values that are wrapped
> +   in containers that give them extra context, like `maybe` values.
> +2. Guix provides a high-level monad API that compensates for Guile's lack of

s/monad API/monad module/ (or “monad library”)

> +   strong types or an interface-like system.

“static types”?

> +3. This API provides the state monad, which allows you to thread state through

s/This API/The `(guix monads)` module/

> +   procedures such that you can pretend it doesn't exist.
> +4. Guix uses the store monad frequently to thread a store connection through
> +   procedures that need it.
> +5. The store monad is really just the state monad in disguise, where the state
> +   value is used to thread the store object through monadic procedures.
> +
> +If you've read this post in its entirety but still don't yet quite get it, don't
> +worry.  Try to modify and tinker about with the examples, and hopefully it will
> +all click eventually!

Maybe link to the “The Store Monad” section of the manual here or
earlier?

I feel we’re asking a lot of work from you, but hopefully the result
will be even more pleasant.  I guess v4 will be ready to go!

Thanks for all the work,
Ludo’.