Am Mo., 30. März 2020 um 16:19 Uhr schrieb John Cowan <xxxxxx@ccil.org>:


On Mon, Mar 30, 2020 at 2:39 AM Marc Nieper-Wißkirchen <xxxxxx@nieper-wisskirchen.de> wrote:

(1) SRFI 158 and the read procedure use the eof object to mark that generator has run out of values.  If SRFI 189 were in existence before, it would have possibly made more sense for generators to use the Maybe protocol. Are there any plans to adapt SRFI 158 or to add adapters to SRFI 189? At the moment, generators cannot yield any eof object asd a value; if they used the Maybe protocol, they could yield any value.

The reason I adopted the EOF object for generators, besides its existing use in read procedures, was that it is deliberately second-class: it is forbidden in the standard to have a datum representation (see eof-object?), though some Schemes allow #!eof or the like.

I think it was the best choice for an end-of-generator object.
 

I will add two more conversion procedures that convert between EOF objects and Nothing, and wrap/unwrap any other object with Just.

That's great. Should SRFI 189 become adopted by Scheme implementers and users, we can think of whether it makes sense to lift the interface of SRFI 158 to Maybes.
 

(2) The "old Scheme way" of returning #f on failure and any other value on success plays nicely with a number of special forms like `cond'/`=>' and `and-let*'. It would be nice if this SRFI provided a similar special forms for Maybe objects.

Good idea.  I'll add maybe-if, which signals an error if its first argument is not a Maybe.

I am thinking of constructs that automatically unpacks the value(s), say "maybe-and-let*" and "maybe-cond":

(maybe-and-let* ((val maybe-value)
                 ((maybe-expr)) ...) ...)

and

(maybe-cond
  ((maybe-value) ...)
  ((maybe-expr) => (lambda (val) ...))
  (else
    ...))

with the obvious semantics.

(3) One disadvantage of the "old Scheme way" to indicate success and failure is that it doesn't play well with multiple values in the success case as the accepting continuation needs to be able to accept an unknown number of arguments. SRFI 189 doesn't have to impose this restriction. It would be very schemely and elegant if the `just' constructor accepted an arbitrary number of values. (Contrary to Haskell, Scheme's procedures can accept more than one argument or none.) This will make a change of the specification of the `either-values' procedure necessary.

I don't quite see how this would work. In order to store multiple values, you have to reify them into a container of some sort anyway.  Can you explain further?

How the values are stored inside the Maybe is a question internal to the implementation.

The generalization I am proposing means that `just' takes an arbitrary number of values and that `maybe-ref' may an arbitrary number of values to `success'. `proc's and `mproc's may take more than one value and may return more than one value.
The other procedures would have to similarly adjusted and the conversion procedures may have to be rethought.

Note that the environment monad defined in SRFI 165 handles multiple values. It would be nice if the monads we are going to define follow a common interface.

The restriction to just one value makes sense for Haskell and ML but not for Scheme, where procedures and continuations can take an arbitrary number of values.
 
(4) As described in the rational, this SRFI will help in catching programming errors by clearly separating types and forcing the programmer to unpack the Maybe objects. Unfortunately, some procedures in the current draft blur the line again, for example `maybe-join' that behaves differently whether the argument is a Maybe object or not. Therefore, there may be the danger that a programming error is not caught because the programmer has/has not unpacked a Maybe object, which `maybe-join' accepts silently.

The maybe-join procedure specifies its argument as _maybe_, which means it is an error if its argument is not a Maybe.  This is a standard specification convention.  But perhaps you mean the behavior if the payload of the argument is or is not a Maybe.  I will add a clarification that that case is an error also.  The point of maybe-join is to reduce a Maybe containing a Maybe to a non-nested Maybe.

Thanks for the clarification. I should have read your document more clearly!

 
(5) Minor: I am not sure whether I think that the names `maybe->lisp' and `lisp->maybe' are a good choice. 

They are not, but I wasn't able to think of any better name for this convention that is not excessively verbose.

We still have some time to come up with some better name if any.

-- Marc

 


John Cowan          http://vrici.lojban.org/~cowan        xxxxxx@ccil.org
Work hard / play hard / die young / rot quickly.