[plt-scheme] SRFI 41

From: Jos Koot (jos.koot at telefonica.net)
Date: Wed Oct 8 15:40:35 EDT 2008

SRFI 41 in PLT is almost an identical copy of the reference implementation. 
I did not yet know it was adopted in PLT, but I am glad to see it there. It 
does not include procedure stream-member. This procedure is given as an 
example in the document. Clearly the example is incorrect.

I suggest:

#lang scheme
(require "streams.ss")

(define (stream-member eql? obj strm)
  (let/ec ec
    (stream-let loop ((strm strm))
        ((stream-null? strm) strm)
        ((eql? obj (stream-car strm)) strm)
        (else (loop (stream-cdr strm)))))))

(define s1 (stream-cons 'a (stream-cons 'b stream-null)))

(stream->list (stream-member eq? 'a s1)) ; --> (a b)
(stream->list (stream-member eq? 'b s1)) ; --> (b)
(stream->list (stream-member eq? 'c s1)) ; --> ( ) ; signals that the 
element is not found.

The solution given by Phil goes wrong on
(stream-member eqv? #f (make-stream #f)) and
(stream-member eqv? #f stream-null)
 because it returns (stream #f) in both cases. It does not show whether the 
returned value, i.e (stream #f), is the last cdr of the stream or a signal 
that the element has not been found. Since the result cannot be empty if the 
element is found it is better to return null-stream in this case.

----- Original Message ----- 
From: "Jens Axel Soegaard" <jensaxel at soegaard.net>
To: <nowgate at yahoo.com>
Cc: <plt-scheme at list.cs.brown.edu>
Sent: Wednesday, October 08, 2008 8:42 PM
Subject: Re: [plt-scheme] SRFI 41

> michael rice skrev:
>> There's a stream-member function given in SRFI 41 that doesn't seem to 
>> work as expected.
>> =================
>> (require srfi/41)
>> (define s1 (stream-cons 'a (stream-cons 'b stream-null)))
>> (define-stream (stream-member eql? obj strm)
>>   (stream-let loop ((strm strm))
>>     (cond ((stream-null? strm) #f)
>>           ((eql? obj (stream-car strm)) strm)
>>           (else (loop (stream-cdr strm))))))
>> ===================
>> Welcome to DrScheme, version 4.1 [3m].
>> Language: Swindle; memory limit: 128 megabytes.
>> > (stream-member equal? 'c s1)
>> #<stream>
>> >
>> ===================
>> Shouldn't the answer be #f?
>> Michael
> The documentation for srfi 41 says:
> (stream-let tag ((var expr) ...) body)
> ... stream-let evaluates the expressions in its body in an environment 
> containing
> the newly-bound variables, returning the value of the last expression 
> evaluated,
> which must yield a stream.
> Since #f is not a stream, the behaviour is undefined.
> Note that evaluating (stream-car (stream-member equal? 'c s1)) gives #f.
> But... The example rises a few questions:
>  Is PLT using the reference implementation of srfi 41?
>  If not, it would be a worth chaning the behaviour of stream-let to
>  match the reference implementation.
>  Was it intentional that this behaviour is undefined?
>   If it is unintentional, maybe an error message would be better
>   than matching the behaviour of the reference implementation?
> -- 
> Jens Axel Søgaard
> _________________________________________________
>  For list-related administrative tasks:
>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme

Posted on the users mailing list.