unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
* bug#26382: [PATCH 0/3] Improve documentation for monads.
@ 2017-04-06  9:15 Chris Marusich
  2017-04-06  9:28 ` bug#26382: [PATCH 1/3] monads: Use intent-revealing parameter names Chris Marusich
  0 siblings, 1 reply; 7+ messages in thread
From: Chris Marusich @ 2017-04-06  9:15 UTC (permalink / raw)
  To: 26382; +Cc: Chris Marusich

Hi,

The following patch series attempts to clarify how one is supposed to
use some of the monad-related syntax that Guix provides.  It also
documents two commonly used forms (mwhen and munless) that were
missing from the manual.

Some of this might seem obvious to someone who is already familiar
with monads.  However, since I only recently learned about monads, a
lot of these details were not obvious to me at all.  For example, I
didn't know that every expression in an mbegin needs to be a monadic
expression (despite having read the manual multiple times).  This was
especially confusing because the same is NOT true for an mlet.  I hope
these patches will help clarify for other monad newbies how this
syntax is supposed to be used.

--
Chris

Chris Marusich (3):
  monads: Use intent-revealing parameter names.
  monads, doc: Improve mwhen and munless documentation.
  monads: Improve mlet, mlet*, and mbegin documentation.

 doc/guix.texi   | 28 +++++++++++++++++++++++++---
 guix/monads.scm | 36 +++++++++++++++++++++++-------------
 2 files changed, 48 insertions(+), 16 deletions(-)

-- 
2.12.0

^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#26382: [PATCH 1/3] monads: Use intent-revealing parameter names.
  2017-04-06  9:15 bug#26382: [PATCH 0/3] Improve documentation for monads Chris Marusich
@ 2017-04-06  9:28 ` Chris Marusich
  2017-04-06  9:28   ` bug#26382: [PATCH 2/3] monads, doc: Improve mwhen and munless documentation Chris Marusich
                     ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Chris Marusich @ 2017-04-06  9:28 UTC (permalink / raw)
  To: 26382; +Cc: Chris Marusich

* guix/monads.scm (mwhen, munless): Rename parameters from 'exp0' and 'exp' to
  'mexp0' and 'mexp', respectively.  This makes it more obvious that these
  expressions must be monadic expressions.
---
 guix/monads.scm | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/guix/monads.scm b/guix/monads.scm
index 0b0ad239d..6933f7f15 100644
--- a/guix/monads.scm
+++ b/guix/monads.scm
@@ -204,23 +204,23 @@ the last one."
 
 (define-syntax mwhen
   (syntax-rules ()
-    "When CONDITION is true, evaluate EXP0..EXP* as in an 'mbegin'.  When
+    "When CONDITION is true, evaluate MEXP0..MEXP* as in an 'mbegin'.  When
 CONDITION is false, return *unspecified* in the current monad."
-    ((_ condition exp0 exp* ...)
+    ((_ condition mexp0 mexp* ...)
      (if condition
          (mbegin %current-monad
-           exp0 exp* ...)
+           mexp0 mexp* ...)
          (return *unspecified*)))))
 
 (define-syntax munless
   (syntax-rules ()
-    "When CONDITION is false, evaluate EXP0..EXP* as in an 'mbegin'.  When
+    "When CONDITION is false, evaluate MEXP0..MEXP* as in an 'mbegin'.  When
 CONDITION is true, return *unspecified* in the current monad."
-    ((_ condition exp0 exp* ...)
+    ((_ condition mexp0 mexp* ...)
      (if condition
          (return *unspecified*)
          (mbegin %current-monad
-           exp0 exp* ...)))))
+           mexp0 mexp* ...)))))
 
 (define-syntax define-lift
   (syntax-rules ()
-- 
2.12.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* bug#26382: [PATCH 2/3] monads, doc: Improve mwhen and munless documentation.
  2017-04-06  9:28 ` bug#26382: [PATCH 1/3] monads: Use intent-revealing parameter names Chris Marusich
@ 2017-04-06  9:28   ` Chris Marusich
  2017-04-08 12:31     ` Ludovic Courtès
  2017-04-06  9:28   ` bug#26382: [PATCH 3/3] monads: Improve mlet, mlet*, and mbegin documentation Chris Marusich
  2017-04-08 12:30   ` bug#26382: [PATCH 1/3] monads: Use intent-revealing parameter names Ludovic Courtès
  2 siblings, 1 reply; 7+ messages in thread
From: Chris Marusich @ 2017-04-06  9:28 UTC (permalink / raw)
  To: 26382; +Cc: Chris Marusich

* doc/guix.texi ((guix) The Store Monad) <mwhen, munless>: Document them.
* guix/monads.scm (mwhen, munless): Clarify their intended use.
---
 doc/guix.texi   | 14 ++++++++++++++
 guix/monads.scm | 12 ++++++++----
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index aa779e38e..a1aae8f6c 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -4027,6 +4027,20 @@ monadic expressions are ignored.  In that sense, it is analogous to
 @code{begin}, but applied to monadic expressions.
 @end deffn
 
+@deffn {Scheme System} mwhen @var{condition} @var{mexp0} @var{mexp*} ...
+When @var{condition} is true, evaluate the sequence of monadic
+expressions @var{mexp0}..@var{mexp*} as in an @code{mbegin}.  When
+@var{condition} is false, return @code{*unspecified*} in the current
+monad.  Every expression in the sequence must be a monadic expression.
+@end deffn
+
+@deffn {Scheme System} munless @var{condition} @var{mexp0} @var{mexp*} ...
+When @var{condition} is false, evaluate the sequence of monadic
+expressions @var{mexp0}..@var{mexp*} as in an @code{mbegin}.  When
+@var{condition} is true, return @code{*unspecified*} in the current
+monad.  Every expression in the sequence must be a monadic expression.
+@end deffn
+
 @cindex state monad
 The @code{(guix monads)} module provides the @dfn{state monad}, which
 allows an additional value---the state---to be @emph{threaded} through
diff --git a/guix/monads.scm b/guix/monads.scm
index 6933f7f15..fe3d5d78f 100644
--- a/guix/monads.scm
+++ b/guix/monads.scm
@@ -204,8 +204,10 @@ the last one."
 
 (define-syntax mwhen
   (syntax-rules ()
-    "When CONDITION is true, evaluate MEXP0..MEXP* as in an 'mbegin'.  When
-CONDITION is false, return *unspecified* in the current monad."
+    "When CONDITION is true, evaluate the sequence of monadic expressions
+MEXP0..MEXP* as in an 'mbegin'.  When CONDITION is false, return *unspecified*
+in the current monad.  Every expression in the sequence must be a monadic
+expression."
     ((_ condition mexp0 mexp* ...)
      (if condition
          (mbegin %current-monad
@@ -214,8 +216,10 @@ CONDITION is false, return *unspecified* in the current monad."
 
 (define-syntax munless
   (syntax-rules ()
-    "When CONDITION is false, evaluate MEXP0..MEXP* as in an 'mbegin'.  When
-CONDITION is true, return *unspecified* in the current monad."
+    "When CONDITION is false, evaluate the sequence of monadic expressions
+MEXP0..MEXP* as in an 'mbegin'.  When CONDITION is true, return *unspecified*
+in the current monad.  Every expression in the sequence must be a monadic
+expression."
     ((_ condition mexp0 mexp* ...)
      (if condition
          (return *unspecified*)
-- 
2.12.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* bug#26382: [PATCH 3/3] monads: Improve mlet, mlet*, and mbegin documentation.
  2017-04-06  9:28 ` bug#26382: [PATCH 1/3] monads: Use intent-revealing parameter names Chris Marusich
  2017-04-06  9:28   ` bug#26382: [PATCH 2/3] monads, doc: Improve mwhen and munless documentation Chris Marusich
@ 2017-04-06  9:28   ` Chris Marusich
  2017-04-08 12:36     ` Ludovic Courtès
  2017-04-08 12:30   ` bug#26382: [PATCH 1/3] monads: Use intent-revealing parameter names Ludovic Courtès
  2 siblings, 1 reply; 7+ messages in thread
From: Chris Marusich @ 2017-04-06  9:28 UTC (permalink / raw)
  To: 26382; +Cc: Chris Marusich

* doc/guix.texi ((guix) The Store Monad) <mlet, mlet*, mbegin>: Clarify
  their intended usage.
* guix/monads.scm (mlet*, mbegin): Update docstrings accordingly.
---
 doc/guix.texi   | 14 +++++++++++---
 guix/monads.scm | 16 +++++++++++-----
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index a1aae8f6c..5cd33a31d 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -4011,8 +4011,15 @@ in this example:
 @deffnx {Scheme Syntax} mlet* @var{monad} ((@var{var} @var{mval}) ...) @
        @var{body} ...
 Bind the variables @var{var} to the monadic values @var{mval} in
-@var{body}.  The form (@var{var} -> @var{val}) binds @var{var} to the
-``normal'' value @var{val}, as per @code{let}.
+@var{body}, which is a sequence of expressions.  As with the bind
+operator, this can be thought of as ``unpacking'' the raw, non-monadic
+value ``contained'' in @var{mval} and making @var{var} refer to that
+raw, non-monadic value within the scope of the @var{body}.  The form
+(@var{var} -> @var{val}) binds @var{var} to the ``normal'' value
+@var{val}, as per @code{let}.  The binding operations occur in sequence
+from left to right.  The last expression of @var{body} must be a monadic
+expression, and its result will become the result of the @code{mlet} or
+@code{mlet*} when run in the @var{monad}.
 
 @code{mlet*} is to @code{mlet} what @code{let*} is to @code{let}
 (@pxref{Local Bindings,,, guile, GNU Guile Reference Manual}).
@@ -4020,7 +4027,8 @@ Bind the variables @var{var} to the monadic values @var{mval} in
 
 @deffn {Scheme System} mbegin @var{monad} @var{mexp} ...
 Bind @var{mexp} and the following monadic expressions in sequence,
-returning the result of the last expression.
+returning the result of the last expression.  Every expression in the
+sequence must be a monadic expression.
 
 This is akin to @code{mlet}, except that the return values of the
 monadic expressions are ignored.  In that sense, it is analogous to
diff --git a/guix/monads.scm b/guix/monads.scm
index fe3d5d78f..2f66f4262 100644
--- a/guix/monads.scm
+++ b/guix/monads.scm
@@ -157,9 +157,14 @@ though BIND is simply binary, as in:
 
 (define-syntax mlet*
   (syntax-rules (->)
-    "Bind the given monadic values MVAL to the given variables VAR.  When the
-form is (VAR -> VAL), bind VAR to the non-monadic value VAL in the same way as
-'let'."
+    "Bind the variables VAR to the monadic values MVAL in BODY, which is a
+sequence of expressions.  As with the bind operator, this can be thought of as
+\"unpacking\" the raw, non-monadic value \"contained\" in MVAL and making VAR
+refer to that raw, non-monadic value within the scope of the BODY.  The
+form (VAR -> VAL) binds VAR to the \"normal\" value VAL, as per 'let'.  The
+binding operations occur in sequence from left to right.  The last expression
+of BODY must be a monadic expression, and its result will become the result of
+the MLET* when run in the MONAD."
     ;; Note: the '->' symbol corresponds to 'is:' in 'better-monads.rkt'.
     ((_ monad () body ...)
      (with-monad monad body ...))
@@ -185,8 +190,9 @@ form is (VAR -> VAL), bind VAR to the non-monadic value VAL in the same way as
 
 (define-syntax mbegin
   (syntax-rules (%current-monad)
-    "Bind the given monadic expressions in sequence, returning the result of
-the last one."
+    "Bind MEXP and the following monadic expressions in sequence, returning
+the result of the last expression.  Every expression in the sequence must be a
+monadic expression."
     ((_ %current-monad mexp)
      mexp)
     ((_ %current-monad mexp rest ...)
-- 
2.12.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* bug#26382: [PATCH 1/3] monads: Use intent-revealing parameter names.
  2017-04-06  9:28 ` bug#26382: [PATCH 1/3] monads: Use intent-revealing parameter names Chris Marusich
  2017-04-06  9:28   ` bug#26382: [PATCH 2/3] monads, doc: Improve mwhen and munless documentation Chris Marusich
  2017-04-06  9:28   ` bug#26382: [PATCH 3/3] monads: Improve mlet, mlet*, and mbegin documentation Chris Marusich
@ 2017-04-08 12:30   ` Ludovic Courtès
  2 siblings, 0 replies; 7+ messages in thread
From: Ludovic Courtès @ 2017-04-08 12:30 UTC (permalink / raw)
  To: Chris Marusich; +Cc: 26382

Chris Marusich <cmmarusich@gmail.com> skribis:

> * guix/monads.scm (mwhen, munless): Rename parameters from 'exp0' and 'exp' to
>   'mexp0' and 'mexp', respectively.  This makes it more obvious that these
>   expressions must be monadic expressions.

Applied, thanks!

Ludo’.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#26382: [PATCH 2/3] monads, doc: Improve mwhen and munless documentation.
  2017-04-06  9:28   ` bug#26382: [PATCH 2/3] monads, doc: Improve mwhen and munless documentation Chris Marusich
@ 2017-04-08 12:31     ` Ludovic Courtès
  0 siblings, 0 replies; 7+ messages in thread
From: Ludovic Courtès @ 2017-04-08 12:31 UTC (permalink / raw)
  To: Chris Marusich; +Cc: 26382

Chris Marusich <cmmarusich@gmail.com> skribis:

> * doc/guix.texi ((guix) The Store Monad) <mwhen, munless>: Document them.
> * guix/monads.scm (mwhen, munless): Clarify their intended use.

Applied!

^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#26382: [PATCH 3/3] monads: Improve mlet, mlet*, and mbegin documentation.
  2017-04-06  9:28   ` bug#26382: [PATCH 3/3] monads: Improve mlet, mlet*, and mbegin documentation Chris Marusich
@ 2017-04-08 12:36     ` Ludovic Courtès
  0 siblings, 0 replies; 7+ messages in thread
From: Ludovic Courtès @ 2017-04-08 12:36 UTC (permalink / raw)
  To: Chris Marusich; +Cc: 26382-done

Chris Marusich <cmmarusich@gmail.com> skribis:

> * doc/guix.texi ((guix) The Store Monad) <mlet, mlet*, mbegin>: Clarify
>   their intended usage.
> * guix/monads.scm (mlet*, mbegin): Update docstrings accordingly.

[...]

> --- a/guix/monads.scm
> +++ b/guix/monads.scm
> @@ -157,9 +157,14 @@ though BIND is simply binary, as in:
>  
>  (define-syntax mlet*
>    (syntax-rules (->)
> -    "Bind the given monadic values MVAL to the given variables VAR.  When the
> -form is (VAR -> VAL), bind VAR to the non-monadic value VAL in the same way as
> -'let'."
> +    "Bind the variables VAR to the monadic values MVAL in BODY, which is a
> +sequence of expressions.  As with the bind operator, this can be thought of as
> +\"unpacking\" the raw, non-monadic value \"contained\" in MVAL and making VAR
> +refer to that raw, non-monadic value within the scope of the BODY.  The
> +form (VAR -> VAL) binds VAR to the \"normal\" value VAL, as per 'let'.  The
> +binding operations occur in sequence from left to right.  The last expression
> +of BODY must be a monadic expression, and its result will become the result of
> +the MLET* when run in the MONAD."
>      ;; Note: the '->' symbol corresponds to 'is:' in 'better-monads.rkt'.
>      ((_ monad () body ...)
>       (with-monad monad body ...))

I applied the patch but decided to leave out the hunk above so that the
docstring remains concise (I view the docstring as a helper rather than
as a reference here.)  Let me know what you think.

And yes, I agree that the fact that the body of ‘mlet’ is a regular
value whereas the body of ‘mbegin’ is a monadic value can be confusing.
Making it this way appeared to cater to the most common use cases,
though.

Thanks for improving the documentation!

Ludo’.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-04-08 12:37 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-06  9:15 bug#26382: [PATCH 0/3] Improve documentation for monads Chris Marusich
2017-04-06  9:28 ` bug#26382: [PATCH 1/3] monads: Use intent-revealing parameter names Chris Marusich
2017-04-06  9:28   ` bug#26382: [PATCH 2/3] monads, doc: Improve mwhen and munless documentation Chris Marusich
2017-04-08 12:31     ` Ludovic Courtès
2017-04-06  9:28   ` bug#26382: [PATCH 3/3] monads: Improve mlet, mlet*, and mbegin documentation Chris Marusich
2017-04-08 12:36     ` Ludovic Courtès
2017-04-08 12:30   ` bug#26382: [PATCH 1/3] monads: Use intent-revealing parameter names Ludovic Courtès

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).