* 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 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 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 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
* 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
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 external index https://git.savannah.gnu.org/cgit/guix.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.