|
From: | Catonano |
Subject: | Re: my latest blog post |
Date: | Sat, 9 Jun 2018 15:03:02 +0200 |
Hi Catonano,
> 2018-06-09 12:39 GMT+02:00 Ricardo Wurmus <address@hidden>:
>
>>
>> Catonano <address@hidden> writes:
>>
>> > Assuming that users read academic articles about programming languages in
>> > order to know your way aroung Guile is not reasonable
>>
>> I fail to see how this follows from Guile’s lack of a macro stepper.
>
>
> Then you were not following
>
> Mark indicated me a paper about the first macro stepper in history
I did follow the discussion and I did see Mark mentioning the paper.
Since Guile does not *have* a macro stepper, reading a paper about how a
macro stepper was implemented is certainly not a requirement to use
Guile.
Obviously, to implement a macro stepper it is useful to know how
to do this. But implementing a macro stepper is not what a Guile user
like myself would ever do.
>> And I have
>> never felt the need to read computer science papers to “know my way
>> around Guile”. (I have not studied computer science, so it isn’t that
>> my background allowed me to skip papers that are mandatory for other
>> users of Guile.)
>>
>> The sentence above seems like an exaggeration to me.
>>
>
> Ok, thans for your contribution
>
>
>> (I say this with no hostility, just with surprise.)
>>
>
> we have a loooong way to go
I sense a lot of hostility in your responses to me and I don’t know why
that is. The first sentence reads like unwarranted sarcasm to me,
because it does not seem to relate to what I wrote; the second sounds
belittling, as if my surprise at what seems like an exaggeration to me
is evidence of how far behind I am in my efforts to ensure that Guix and
Guile a welcoming to newcomers.
I’m sorry that you don’t find anything useful in my response above,
which relates my personal experience with Guile as someone who is not a
computer scientist. I hoped it would be a useful data point.
As I find discussions like this exceptionally draining and discouraging,
detrimental to my ability to volunteer time to free software, I will
take some time off from this discussion after trying to respond to your
other message to me in this thread.
>> > The monad accessing the daemon, how would I delve in it ?
>>
>> The Guix manual should explain it fully, while assuming that the concept
>> of a monad is known (because that’s not a Guix or Guile invention).
>
>
> And how would I know what a monad is without reading academic materials ?
>
> Maybe Haskell is a requirement in order to use Guile//Guix ?
>
> "assuming that the concept of a monad is known" is a problem.
By analogy, do you think that assuming the concept of recursion would be
a problem? Or the concept of a closure? Would you say that this should
be explained in the *Guix* manual? (These are sincere questions.)
We are using both of these constructs. We are also using delayed
evaluation in the form of streams. Luckily, those are provided as a
Guile library and are thus documented in the *Guile* manual.
> Someone would want to _learn_ what a monad is AND how it can be implemented
> in scheme, by dissecting this Guix macro based feature
I used “,expand” in the past to see the expansion of a macro
_expression_. Here’s an example with the state monad:
--8<---------------cut here---------------start------------->8---
scheme@(guile-user)> ,expand (with-monad %state-monad (return 1))
$3 = (let ((value 1))
(lambda (state)
((@@ (guix monads) values) value state)))
--8<---------------cut here---------------end--------------->8---
This shows us that returning a monadic value in the state monad is the
same as returning a procedure that takes some state and returns it
alongside the value.
The Guix manual says about the things that we used:
--8<---------------cut here---------------start------------->8---
-- Scheme Syntax: with-monad MONAD BODY ...
Evaluate any ‘>>=’ or ‘return’ forms in BODY as being in MONAD.
-- Scheme Syntax: return VAL
Return a monadic value that encapsulates VAL.
--8<---------------cut here---------------end--------------->8---
Earlier, it also says something about what monads are all about:
--8<---------------cut here---------------start------------->8---
This is where the ‘(guix monads)’ module comes in. This module
provides a framework for working with “monads”, and a particularly
useful monad for our uses, the “store monad”. Monads are a construct
that allows two things: associating “context” with values (in our case,
the context is the store), and building sequences of computations (here
computations include accesses to the store). Values in a monad—values
that carry this additional context—are called “monadic values”;
procedures that return such values are called “monadic procedures”.
--8<---------------cut here---------------end--------------->8---
We’ve just seen the first part about associating “context” (in this case
some state) with values. The second part requires a larger _expression_
to see how this is useful.
The Guix manual has an example right there:
--8<---------------cut here---------------start------------->8---
-- Scheme Syntax: >>= MVAL MPROC ...
“Bind” monadic value MVAL, passing its “contents” to monadic
procedures MPROC...(1). There can be one MPROC or several of them,
as in this example:
(run-with-state
(with-monad %state-monad
(>>= (return 1)
(lambda (x) (return (+ 1 x)))
(lambda (x) (return (* 2 x)))))
'some-state)
⇒ 4
⇒ some-state
--8<---------------cut here---------------end--------------->8---
So this is an _expression_ that somewhat uselessly computes the number 4
in a context where “some-state” is present. We can use ,expand in the
REPL to see how this works, this time with a slightly simpler
_expression_ that would compute 1 + 1 in some given context:
--8<---------------cut here---------------start------------->8---
scheme@(guile-user)> ,expand (with-monad %state-monad
(>>= (return 1)
(lambda (x) (return (+ 1 x)))))
$6 = (let ((mvalue
(let ((value 1))
(lambda (state)
((@@ (guix monads) values) value state))))
(mproc (lambda (x)
(let ((value (+ 1 x)))
(lambda (state)
((@@ (guix monads) values) value state))))))
"Bind MVALUE, a value in the state monad, and pass it to MPROC."
(lambda (state)
((@@ (guix monads) call-with-values)
(lambda () (mvalue state))
(lambda (value state) ((mproc value) state)))))
--8<---------------cut here---------------end--------------->8---
This looks similar to the previous _expression_ (see “mvalue”). Looking
at the body, we see that this is a procedure that takes some state,
computes a new value by passing the state to “mvalue”, and then passes
that to the next action (the last lambda in the original _expression_).
I don’t think that the presence of the relevant documentation in the
Guix manual and the existence of a macro-expansion facility should be
taken as evidence that we “think that the code should be kept obscure
and unaccessible”.
I would also like to state, though, that the use of the state monad is
hardly essential for the purpose of extending or contributing to Guix.
If you find a way to improve the existing documentation, you know from
our past interactions that the maintainers and developers are very
welcoming of additions or changes to the manual.
--
Ricardo
[Prev in Thread] | Current Thread | [Next in Thread] |