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

> On Dec 21, 2015, at 6:22 PM, Alexis King <[email protected]> wrote:
> 
> As anyone familiar with my collections library is aware, my library makes very
> heavy use of streams. So far, they seem to have served it well, but there is 
> one
> obvious problem that has to do with how streams are printed. Having the 
> ability
> to inspect values in the REPL is obviously useful, but Racket streams always
> print out as the opaque value #<stream>, which is effectively useless. The
> programmer is required to force the stream in some way, usually by converting 
> it
> to a list. Of course, if the stream is infinite, this has some pretty major
> problems, too.
> 
> Jack Firth and I have been discussing this problem a little bit[1], and I’d 
> like
> to try and come up with a solution, even if it is imperfect. The obvious other
> languages I’ve looked at so far[2] don’t solve this in any elegant way, they
> mostly just accept subpar behavior for infinite streams. I think it might be
> worth attempting to come up with superior behavior for Racket streams.
> 
> One thing we have discussed is that gen:countable has a notion of finiteness:
> specifically, any collection may report whether or not it is `known-finite?`. 
> If
> it returns #f, no information is gained, but if it returns `#t`, it’s at least
> known to be finite. This certainly seems like useful information for printing
> purposes, but it also isn’t necessarily strong enough: it would be very
> difficult to automatically track, for example, that `map`ping over a finite
> stream would still be finite. Still, certain operations, such as `take`, could
> make very strong guarantees about the length of their results, which could be
> useful information when printing.
> 
> At an absolute bare minimum, elements of a stream that have already been 
> forced
> could be safely printed, but this would potentially cause confusion over where
> streams arbitrary stop printing. It also probably wouldn’t come up very often,
> given that most of the time streams are the results of various filtering,
> mapping, or other such operations, and values won’t have been forced yet,
> anyway.
> 
> With all this in mind, does anyone have any strong feelings about printing
> streams? Is the current scheme adequate? Is it feasible to try and create some
> kind of “best-effort” algorithm, or are the optimistic algorithms of Haskell 
> and
> Clojure valid compromises? Is this a change that should be implemented within
> the collections package, or is it something that belongs in racket/stream?
> 
> Alexis
> 
> P.S. This problem can likely be more or less solved in DrRacket through some
> sort of interactive snips in the REPL. This is a great idea, and it’s 
> something
> I’ve considered already, but it does not eliminate all the valid use-cases 
> when
> one might want better textual output.
> 
> [1]: https://github.com/lexi-lambda/racket-collections/issues/4
> [2]: https://gist.github.com/lexi-lambda/6985d77048f458960468

-- 
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/5FEFFA0A-CBED-4A0D-B5B0-76FCD258EEE0%40knauth.org.
For more options, visit https://groups.google.com/d/optout.

Reply via email to