The definition of stream-member given in the text of SRFI-41 is incorrect. The problem is inconsistent typing: one branch of the cond returns #f, which is not a stream, while another branch of the cond returns strm, which is a stream. Here is a definition of stream-member? which returns either #t or #f; it uses normal define, not stream-define, and normal let, not stream-let:
(define (stream-member? eql? obj strm)
(let loop ((strm strm))
(cond ((stream-null? strm) #f)
((eql? (stream-car strm) obj) #t)
(else (loop (stream-cdr strm))))))
Given that, (stream-member? equal? 'c (stream 'a 'b)) evaluates to #f, as you expect.
Another definition of stream-member, the one that was intended by SRFI-41, is:
(define-stream (stream-member eql? obj strm)
(stream-let loop ((strm strm))
(cond ((stream-null? strm) (stream #f))
((eql? obj (stream-car strm)) strm)
(else (loop (stream-cdr strm))))))
That definition type-checks because both branches of the cond evaluate to a stream. Given that definition, (stream-car (stream-member equal? 'c (stream 'a 'b))) evaluates to #f, and (stream-car (stream-member equal? 'a (stream 'a 'b))) evaluates to a.
Note that stream-member is not defined in SRFI-41; it is just an example in the text (worse, it is an incorrect example in the text). If PLT includes stream-member in its version of SRFI-41, that is an extension of SRFI-41. If PLT wants to extend SRFI-41, it would be better to define the library in such a way that it is loaded by (require srfi/41-extended-by-PLT) or some such mechanism. By taking the liberty of extending the base definition of SRFI-41, PLT confuses users and makes code written using its extended version of SRFI-41 non-portable to other Scheme systems that adhere to SRFI-41 as it is written.
I will forward this note to the SRFI-41 mailing list.
Phil
On Wed, Oct 8, 2008 at 1:11 PM, michael rice
<nowgate@xxxxxxxxx> wrote:
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
|
_________________________________________________
For list-related administrative tasks:
http://list.cs.brown.edu/mailman/listinfo/plt-scheme