Email list hosting service & mailing list manager

Re: Custom state variables Marc Nieper-Wißkirchen (14 Feb 2019 08:04 UTC)
Re: Custom state variables Marc Nieper-Wißkirchen (14 Feb 2019 09:29 UTC)
Re: Custom state variables Alex Shinn (17 Feb 2019 15:22 UTC)
Re: [scheme-reports-wg2] Re: Custom state variables Marc Nieper-Wißkirchen (17 Feb 2019 16:15 UTC)

Re: [scheme-reports-wg2] Re: Custom state variables Marc Nieper-Wißkirchen 17 Feb 2019 16:15 UTC

Am So., 17. Feb. 2019 um 16:22 Uhr schrieb Alex Shinn <xxxxxx@gmail.com>:

>> SRFI 165 is both separating from SRFI 159 the part of SRFI 159's API
>> that deals with the environment monad into a reusable library as well
>> as extending this API in several ways and specifying its semantics
>> more precisely:
>>
>> (1) Underlying the semantics of SRFI 159 is the environment monad. A
>> formatter of SRFI 159 is nothing but a monadic value of this monad.
>
>
> I think you mean monadic function.

If C is a category of types and F a monad on C, I am calling a value v
of a type of the form C(T) a "monadic value of type T (with respect to
the monad F)".

This seems to be the standard naming convention; it is used at
Wikipedia and in the Haskell community as well.

A "monadic function" would be a function from a type S into a monadic
type C(T) such that the "bind" operator (>>=) takes a monadic value
and a monadic function and returns a monadic value.

>>
>> [There is a slight error in the text of SRFI 159, which states that a
>> formatter is an environment  monad.]
>
>
> It says "essentially a monad" in intentionally hand-wavy terms.
> I didn't want to overcomplicate the SRFI, nor restrict it in any way.

As long as it doesn't confuse readers, it is probably not an important
point. I just wanted to get the terminology right when describing the
relationship of SRFI 165 to SRFI 159.

> I think SRFI 165 looks useful in its own right, but would want to see
> wider adoption and usage before wanting to define the formatters
> in terms of it.  I could probably be convinced, but this seems too new
> and too late for the Tangerine edition.

It also took one edition for the change from SRFI 121 to SRFI 158 so
there shouldn't be any rush.

> If we don't use monads for
> anything else in the large language it seems a premature abstraction.
>
> [Note there's an alternate implementation of SRFI 159 that uses only parameters,
> without passing any explicit state, which is arguably not an env monad.]

The environment monad is an abstract concept, not a concrete data
type. In particular, SRFI 165 could alternatively be coded with
parameters as well. Still, SRFI 165 and SRFI 159 have the concept of
the environment monad at its core.

Of course, if SRFI 159 is based on SRFI 165 (regardless of the
implementation), a user will be able to make use of the SRFI 165
procedures for formatters as well. At least two opportunities to use
SRFI 165 with SRFI 159's formatters seem to be worth mentioning:

(a) The only ways to pass data locally between SRFI 159 formatters in
a sequence is either to modify some non-local state or to pass the
data using state variables. The former approach is not very Schemely
(read as: non-functional). The latter approach likely has a runtime
overhead.

SRFI 165 allows formatters (called "monadic values" in SRFI 165) to
carry values with them that can be passed to the next value in a
sequence. For example, "(return 42)" is a formatter that does nothing
but carries the value "42". The "nothing" formatter of SRFI 159 is
just "(return (if #f #f))". Values can be passed using "bind" instead
of "sequence".

For example:

(define (f n) (sequence (displayed (number->string n)) (return (+ n 1))))

(show #f (bind (f 0) f f f)) ; => "0123"

(b) SRFI 165 defines an interface similar to Haskell's "do" notation
that can be used to create monadic values (and thus SRFI 159 if that
SRFI is compatible with SRFI 165), name "make-computation" (should
sometime a revised version of SRFI 159 be adopted, it could make sense
to re-export "make-computation" under the name "make-formatter").

"make-computation" can be used when we want to combine formatter with
other higher-level abstractions. Say I have a container, for which a
"for-each" but no "fold" is being defined. Using "make-computer", we
can still create a formatter displaying each container element in a
row:

(make-computation
  (lambda (format)
    (container-for-each (lambda (el) (format (displayed el))) container)))

>> (2) Independently to the above, SRFI 165 changes what the runtime
>> representation of a state variable can be. [...]
>
>
> Paraphrasing: "Are they symbols or identifiers bound to state objects?"
>
> In general, something that acts like a variable identifier should be
> hygienic, and it was most likely a mistake for SRFI 159 to use symbols.
>
> Having sorted out implementation details to my satisfaction, the only
> argument I can think to prefer symbols is relative ease of loading
> formatters from text files (e.g. gettext, one of the other outstanding issues
> that went untouched in the original discussion).  You can evaluate
> an expression in a safe (srfi 159) sandbox and still be able to refer
> to new parameters, e.g. the gettext args, without having to worry about
> hygiene (you could even compile by hand if eval made you nervous).
> By contrast, if the state vars are hygienic you need to eval in the right
> combination of environments, which may or may not be safe.
>
> It's a weak argument and doesn't convince me.
>
> I'd be open to writing a new SRFI which is a modified SRFI 159
> having hygienic state variables hygienic, assuming other members
> of WG2 would be willing to revote and include this in place of SRFI 159.

I am wondering whether anyone who voted for SRFI 159 had paid much
attention to the particular choice of options SRFI 159 had done here.

So for the time being, I will leave the draft of SRFI 165 as it is
(and do not change it to non-hygienic variables). I will be able to
provide an implementation of SRFI 159 (by adapting the reference
implementation) that builds upon SRFI 165.

Marc