Hi, Amirouche Boubekki <amirou...@hypermove.net> writes: [...] > Now, I got another idea what if I replace the 'cons' returned > by the traversi procedures by 'values' and replace the > lambda with 'delay' with some use of 'force' at the correct > places. It will result in the following procedures: > > (define-public (list->stream lst) > (let loop ((lst lst)) > (if (null? lst) > (delay (values #f #f)) > (delay (values (car lst) (loop (cdr lst))))))) > > (define-public (stream->list stream) > (let loop ((stream stream) > (out '())) > (call-with-values (lambda () (force stream)) > (lambda (value next) > (if next > (loop next (cons value out)) > (reverse! out)))))) > > (define-public (stream-map proc stream) > (let loop ((stream stream)) > (call-with-values (lambda () (force stream)) > (lambda (value next) > (if next > (delay (values (proc value) (loop next))) > (delay (values #f #f)))))))
This code assumes that promises can store multiple values. Although Guile's legacy core promises *accidentally* support multiple values today, there's no guarantee that they will continue to do so in the future. None of the standards allow this, and Guile's manual states in the documentation for 'delay' that "The effect of <expression> returning multiple values is unspecified." Supporting multiple values in promises makes them more complex, and inevitably less efficient. SRFI-45 promises are simpler than Guile's legacy core promises in two ways: (1) they do not include built-in thread synchronization, and (2) they do not support multiple values. I would recommend using SRFI-45 promises. Although they are implemented in Scheme, last I checked I found that they were about as fast as Guile's legacy core promises implemented in C, presumably because of the built-in thread synchronization in our core promises. In any case, I would strongly recommend against writing code that assumes that Guile's promises can hold multiple values. Regards, Mark