I’ve looked into the internals of streams before, and my understanding is that
they are, in large part, ported from a different Scheme implementation. Hence
the use of mutable pairs and lack of promises, as well as some degree of
compatibility with SRFI 41.

I cannot comment on individual implementation decisions, nor would I expect many
people to be able to. A lot of things can be explained by the caching, though:
streams need to cache their results, and while promises get this for free, an
implementation that does not have access to promises does not get such a luxury.
This is why mutable pairs are necessary, along with the layers of indirection.

Is this a good implementation? It’s certainly not very Racket-y. I think
rewriting it would be warranted iff we can maintain compatibility, maintain or
improve performance, and help to address some of the issues with printing and
the API. Rewriting it for the sake of making it more idiomatic would be good,
too, but it seems like wasted effort if we aren’t fixing anything from a user’s
perspective but could potentially break compatibility in subtle ways. On the
other hand, reducing code complexity is always a win.

Alexis

> On Dec 22, 2015, at 10:58 AM, Alex Knauth <[email protected]> wrote:
> 
> I was curious about how stream printing could work, so I inserted a 
> prop:custom-write property that printed the `promise` field. 
> 
> But then I was a bit surprised to find it was not a promise, but a mutable 
> pair containing the symbol 'eager and a #<stream-pare> struct. The 'eager is 
> confusing because it shows up even when it is an unforced lazy stream, and 
> the mcons is confusing because streams are supposed to be immutable.
> 
> I also looked more closely at stream-cons, and it looks like `(stream-cons x 
> y)` is equivalent to this:
> (make-stream
> (mcons
>  'eager
>  (make-stream-pare
>   (make-stream (mcons 'lazy (lambda () (make-stream
>                                         (mcons 'eager x)))))
>   (make-stream (mcons 'lazy (lambda () y))))))
> 
> Where the `x` is wrapped in not just one `(make-stream (mcons ...))`, but two 
> `(make-stream (mcons ...))`s. I would think only the lambda would be 
> necessary. What are all these extra `make-streams` and `mcons`s around all 
> the elements of the stream, even when they are not streams themselves? 
> 
> Also is there a reason why streams use this instead of promises?
> 
> Alex Knauth

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-dev/BE12CDB8-84B7-4376-9350-FB53F5E41F23%40gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to