Email list hosting service & mailing list manager

Iteration revisited Daphne Preston-Kendal (25 Oct 2021 06:30 UTC)
Re: Iteration revisited Marc Nieper-Wißkirchen (25 Oct 2021 10:37 UTC)
Re: Iteration revisited Daphne Preston-Kendal (25 Oct 2021 11:27 UTC)
Re: Iteration revisited Marc Nieper-Wißkirchen (25 Oct 2021 11:43 UTC)
Re: Iteration revisited John Cowan (25 Oct 2021 18:53 UTC)
Re: Iteration revisited siiky (25 Oct 2021 20:26 UTC)
Re: Iteration revisited Amirouche BOUBEKKI (26 Oct 2021 05:26 UTC)
Re: Iteration revisited Marc Feeley (26 Oct 2021 12:06 UTC)
Re: Iteration revisited Marc Nieper-Wißkirchen (26 Oct 2021 12:17 UTC)
Re: Iteration revisited Marc Feeley (27 Oct 2021 14:13 UTC)
Re: Iteration revisited Marc Nieper-Wißkirchen (27 Oct 2021 15:13 UTC)
Re: Iteration revisited Marc Nieper-Wißkirchen (26 Oct 2021 07:14 UTC)
Re: Iteration revisited John Cowan (28 Oct 2021 00:48 UTC)
Re: Iteration revisited Marc Nieper-Wißkirchen (28 Oct 2021 14:23 UTC)
Re: Iteration revisited John Cowan (28 Oct 2021 19:17 UTC)
Re: Iteration revisited Marc Nieper-Wißkirchen (28 Oct 2021 19:42 UTC)
Re: Iteration revisited Marc Nieper-Wißkirchen (29 Oct 2021 06:06 UTC)
Re: Iteration revisited Marc Nieper-Wißkirchen (26 Oct 2021 07:27 UTC)
Re: Iteration revisited John Cowan (27 Oct 2021 15:35 UTC)
Re: Iteration revisited John Cowan (28 Oct 2021 00:31 UTC)
Re: Iteration revisited Marc Nieper-Wißkirchen (28 Oct 2021 17:57 UTC)
Re: Iteration revisited Amirouche BOUBEKKI (25 Oct 2021 11:12 UTC)
Re: Iteration revisited Marc Nieper-Wißkirchen (25 Oct 2021 11:28 UTC)
Re: Iteration revisited John Cowan (28 Oct 2021 00:13 UTC)
Re: Iteration revisited Marc Nieper-Wißkirchen (28 Oct 2021 17:38 UTC)

Re: Iteration revisited Marc Feeley 27 Oct 2021 14:13 UTC

> On Oct 26, 2021, at 8:16 AM, Marc Nieper-Wißkirchen <xxxxxx@gmail.com> wrote:
>
> Am Di., 26. Okt. 2021 um 14:06 Uhr schrieb Marc Feeley - feeley at iro.umontreal.ca (via srfi-discuss list) <xxxxxx@srfi.schemers.org>:
>
> > On Oct 26, 2021, at 1:26 AM, Amirouche BOUBEKKI <xxxxxx@hyper.dev> wrote:
> >
> > Welcome to the conversation :)
> >
> >>
> >
> >> If I have a list of ports `l` and want to read the contents of all of
> >>
> >
> >> them, `(map (cute read-string #f <>) l)` is one "obvious" way to go.
> >>
> >
> >> Another probably better example is #f, although not related to
> >>
> >
> >> generators & whatnot, which is commonly used as the "null value". Except
> >>
> >
> >> when it is a valid input or output value. And that's why `maybe` from
> >>
> >
> >> SRFI 189 is useful.
> >>
> >
> >> siiky
> >
> > In another thread the Maybe approach was also mentioned.
> >
> >
> > The problem I have with eof-object in generator is that eof-object is not a disjoint type for a dijoint behavior such as described in null object pattern [0].
> > In a way that is similar to JavaScript's `undefined` that shows up in code or errors, without giving information about what is the actual context or problem.
>
> A solution to this is to (conceptually) add a parameter to input procedures, i.e. read, read-char, read-string, etc which is the object to return upon reaching the end of file (or end of stream).  The end of file can then be detected unambiguously by passing a unique object as this parameter and checking for eq? on the result of the input procedure.
>
> For `read' and friends, this is not a problem because an eof object is an object that cannot be read (by definition).

Unless you are using a Scheme system (such as Gambit, Chez, bigloo, etc) where the end-of-file object has an external representation, such as #!eof in Gambit and Chez.  The need to “serialize/deserialize” the end-of-file object happens in practice, for example if you want to do a remote procedure call and some parameter contains the end-of-file object or the result is the end-of-file object.

Designing a language without considering these advanced use-cases will bite you down the line when you want to do these things and the only way is to add ugly special cases for the serialization/deserialization of the end-of-file object (instead of simply using write and read).

> An optional parameter could be added to the input procedures but this would not be my choice.  Instead the R7RS eof-object procedure should be turned into a parameter object (intitially bound to a “standard” end of file object) and the input procedures would be required to return the value bound to the eof-object parameter object upon reaching the end of file).  I checked the R7RS and it seems this extension does not violate the current spec.
>
> Detecting the end of file unambiguously could then be done like this:
>
>   (let ((my-eof (list 'unique)))
>     (let ((data (parameterize ((eof-object my-eof)) (read port))))
>       (if (eq? data my-eof)
>           ...    ;; EOF reached
>           ...))) ;; EOF not yet reached
>
> While this works, it is obviously a hack in the sense that creating a unique object and testing against is not part of the abstract problem to be solved.
>
> An API that makes such hacks necessary is not a good API IMO.

This is not a “hack”… it is a well known pattern in Scheme/Lisp to handle special cases such as a dictionary lookup of a key that is not in the dictionary.  For this Gambit has the procedure (table-ref table key [default-value]) where default-value is optional and if it is specified and the key is not found the result is default-value.  By passing a unique object for this parameter it is possible to test if the dictionary contained the key with an eq? test of the unique object.  Racket has (dict-ref dict key [failure-result]) with similar spec and it is used to implement (dict-has-key? dict key).

In the case of read, an eof-object parameter object allows setting up a custom protocol to detect the “end of stream” between a stream generator (the read procedure) and the code that consumes the stream.

>
> PS: I am not sure whether your suggestion would agree with the R7RS spec. The R7RS spec says that `eof-object?' detects end-of-file objects and that `eof-object' returns end-of-file objects. This is not the case within the dynamic extent of the above parameterize.

In the R7RS the eof-object procedure is not a parameter object, so according to R7RS it is an error for a program to do (parameterize ((eof-object …)) …) or (eof-object 'my-eof).  Because it is an error the implementation (or SRFI spec) can do whatever it wants… i.e. all bets are off.  This is the traditional way in RnRS specifications to leave the door open for extensions such as the one I outlined and any extension proposed in a SRFI or even R8RS.

Marc