From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp10.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id QJF7Epkq6WOBQgAAbAwnHQ (envelope-from ) for ; Sun, 12 Feb 2023 19:06:17 +0100 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp10.migadu.com with LMTPS id uMV1EZkq6WPWCAAAG6o9tA (envelope-from ) for ; Sun, 12 Feb 2023 19:06:17 +0100 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id AD8DFE9B2 for ; Sun, 12 Feb 2023 19:06:16 +0100 (CET) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pRGjk-0002Ss-AA; Sun, 12 Feb 2023 13:06:04 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pRGji-0002S7-Hq for guix-patches@gnu.org; Sun, 12 Feb 2023 13:06:02 -0500 Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pRGji-0006H6-8s for guix-patches@gnu.org; Sun, 12 Feb 2023 13:06:02 -0500 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1pRGji-0003bM-4S for guix-patches@gnu.org; Sun, 12 Feb 2023 13:06:02 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#61214] [PATCH guix-artwork] website: posts: Add Dissecting Guix, Part 2: The Store Monad. Resent-From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 12 Feb 2023 18:06:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 61214 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: "(" Cc: 61214@debbugs.gnu.org Received: via spool by 61214-submit@debbugs.gnu.org id=B61214.167622516013836 (code B ref 61214); Sun, 12 Feb 2023 18:06:02 +0000 Received: (at 61214) by debbugs.gnu.org; 12 Feb 2023 18:06:00 +0000 Received: from localhost ([127.0.0.1]:46677 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1pRGjf-0003b4-To for submit@debbugs.gnu.org; Sun, 12 Feb 2023 13:06:00 -0500 Received: from eggs.gnu.org ([209.51.188.92]:32982) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1pRGjd-0003ar-V9 for 61214@debbugs.gnu.org; Sun, 12 Feb 2023 13:05:58 -0500 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pRGjY-0006GZ-OU; Sun, 12 Feb 2023 13:05:52 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:In-Reply-To:Date:References:Subject:To: From; bh=Okaq730h8wYvHQOm2YVVYLOKKlrw6QuXnOZHEFM49p0=; b=lgq6UJi+IzZJ/V2u59/v sT2OxMhJUydi1OPpqRhtOTMiIfrL0kDdTGHVH4aSfn9WHmzyQPUgt3C9baW4y25zr5waD9Qg0PNkh uiYQZhWsrQLyQy5t3JgMyCqo7/zZTN/hA8PtQ1ZaDSHZ+KaG29454owcJ/90wGXmHAw1zTrkADiZg fhIGnozZXsMtE0iXZuSZ9SLtw62BYx1vPtVbH+3XyJdV2Uatvbxs/zLgmgzdJaEEtcXh9lVZvEbhh CGTb5xreBRqG8dCcleM5Re66u8vkDWMgImlQo0GEku5WFwlq1TV5/fDHcX/5ESTrIDuODK1RmSx1c o7XfhKZuY18P+Q==; Received: from [185.228.228.230] (helo=ribbon) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pRGjX-00076f-SP; Sun, 12 Feb 2023 13:05:52 -0500 From: Ludovic =?UTF-8?Q?Court=C3=A8s?= References: <20230201172821.3072-1-paren@disroot.org> <20230203073624.2338-1-paren@disroot.org> Date: Sun, 12 Feb 2023 19:05:43 +0100 In-Reply-To: <20230203073624.2338-1-paren@disroot.org> (paren@disroot.org's message of "Fri, 3 Feb 2023 07:36:24 +0000") Message-ID: <87h6vqlpxk.fsf_-_@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+larch=yhetil.org@gnu.org Sender: guix-patches-bounces+larch=yhetil.org@gnu.org X-Migadu-Flow: FLOW_IN X-Migadu-Country: US ARC-Seal: i=1; s=key1; d=yhetil.org; t=1676225177; a=rsa-sha256; cv=none; b=IhpVl7ZCiKfOVaanKDv87yv8vYODu+4TxDfCheA2c/2Th7d1R8VEiKNZGDbVlCSoqe8/JI l6r7Jx2Lz87VPAJOtPATGOzMIMagB8YrIT9e8uOg6y4cUxQJtEUXXoGBcwXkfC9HT/7RCX 7/JnTioMXRhuZdiMYdyHlFvoV1XgG2boa0lpNUq5fMmRJTU3SE3BV10ehWfdXCzgdUjRt0 19lvcQ7WRpMfBn6itJ8xFnq0RVOn3x8KeqVZrs+k+VYTWFACvrdZJVMEcw/0+9Bgml9Ykw Oy8Gs9u9DzmOvQc6HRtlymKwvl+/SRdE1+HWe224xj+LCAIVJ/EhfwvLO+la1w== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=gnu.org header.s=fencepost-gnu-org header.b=lgq6UJi+; spf=pass (aspmx1.migadu.com: domain of "guix-patches-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-patches-bounces+larch=yhetil.org@gnu.org"; dmarc=pass (policy=none) header.from=gnu.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1676225177; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding:resent-cc: resent-from:resent-sender:resent-message-id:in-reply-to:in-reply-to: references:references:list-id:list-help:list-unsubscribe: list-subscribe:list-post:dkim-signature; bh=Okaq730h8wYvHQOm2YVVYLOKKlrw6QuXnOZHEFM49p0=; b=KT89xaon58HCiAX7PRwxTOz6Cu3RUZ4zg1bIwx94pe3jRgYF4nwrlz0M0C6qql1+hYxouv VtbCAYuJ5xcTIFTfaHVV4jtOnhZNOts7opFV/O82jEdQiiaaPtScWsGHR+OVVPELS9YH3m wSoTuxB+Iow/WvZb02NDjTF7soz4bxu9PHXaZPCAjHAD5NuhlQcfG6duXhRFqBI9wBGv77 292mZ0chPyFuKkohJSHW2Z5GeME7KjPSmc0Kpl+haJZ5N83YYgbhU0KuNJD5VS2vR4IhEE FkKwXmb/neIdRrOF9h4fHdPQNeb7pcebfk65qgmy4EN4Y5arT/RAddQ5/NyK/w== X-Migadu-Spam-Score: -4.02 X-Spam-Score: -4.02 X-Migadu-Queue-Id: AD8DFE9B2 X-Migadu-Scanner: scn1.migadu.com Authentication-Results: aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=gnu.org header.s=fencepost-gnu-org header.b=lgq6UJi+; spf=pass (aspmx1.migadu.com: domain of "guix-patches-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-patches-bounces+larch=yhetil.org@gnu.org"; dmarc=pass (policy=none) header.from=gnu.org X-TUID: EKlLJSgfsy5J Hello! "(" 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-par= t-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=E2=80=99m wary of acronyms (they can easily make things impenetrable) so I=E2=80=99d 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=E2=80=99s comment: a few sentences of a higher-level int= ro showing where this fits in the big picture would be great! It would be nice to stress, also, that one doesn=E2=80=99t _need_ to know a= bout monads to use the various programming interfaces of Guix; instead, it=E2=80= =99s a thing for someone who=E2=80=99d like to get a deep dive into the internal= s of Guix. I=E2=80=99m saying this because we FP people, especially in the Haskell cam= p, are sometimes very good at making things look fancy and complicated. The last thing we=E2=80=99d 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`_ v= alues, > +representing a value that may or may not exist. `maybe` is a very common ^ Maybe add something like =E2=80=9CFor example, one might write a function t= hat divides two integers such that it returns special value `nothing` when the divisor is zero, and `maybe 5` when passed `15` and `3`.=E2=80=9D (I couldn=E2=80=99t think of a better example but you get the idea. :-)) > +feature of strongly-typed functional languages, and you'll see it all ov= er 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 =E2=80=9CNothing=E2=80=9D. > +# New Wheel, Old Wheel > + > +Now that we've reinvented the wheel, we'd better learn to use the origin= al > +wheel. Guix provides a generic, high-level monads API, along with the t= wo > +generic monads `%identity-monad` and `%state-monad`, and the Guix-specif= ic > +`%store-monad`. Since `maybe` is not one of them, let's integrate our v= ersion > +into the Guix monad system! > + > +First we'll make the API available: Maybe =E2=80=9CFirst, let=E2=80=99s import that module:=E2=80=9D? > +```scheme > +(use-modules (guix monads)) > +``` > + > +To define a monad's API in Guix, we simply use the `define-monad` macro,= and =E2=80=9CTo define a monad in Guix, we use `define-monad`=E2=80=9D (In general, I=E2=80=99d avoid =E2=80=9Csimply=E2=80=9D because whether it= =E2=80=99s =E2=80=9Csimple=E2=80=9D depends on one=E2=80=99s background.) > +`bind` is just the procedure that we use to compose monadic procedure ca= lls > +together, and `return` is the procedure that wraps values in the most ba= sic form > +of the monad. A properly implemented `bind` and `return` must follow th= ese > +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 =E2=80=9C=E2=87=92 #t=E2=80=9D instead of =E2=80=9C;; #t=E2=80= =9D, 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 lac= k of s/monad API/monad module/ (or =E2=80=9Cmonad library=E2=80=9D) > + strong types or an interface-like system. =E2=80=9Cstatic types=E2=80=9D? > +3. This API provides the state monad, which allows you to thread state t= hrough 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 thr= ough > + 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 i= t, don't > +worry. Try to modify and tinker about with the examples, and hopefully = it will > +all click eventually! Maybe link to the =E2=80=9CThe Store Monad=E2=80=9D section of the manual h= ere or earlier? I feel we=E2=80=99re 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=E2=80=99.