I use sequences often in the context of database query results. I don't
get as much mileage from streams, but I really like the idea of printing
stream elements. Something like current-stream-display-count that
defaults to a small number would be nice in non-interactive mode, and a
widget to navigate the stream contents in DrRacket would be perfect.
Having something similar for sequences would be convenient but a bit
invasive (a bug involving displayln prematurely consuming a sequence
could be terrible).
On 2015-12-21 3:22 PM, Alexis King 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/567891DF.6060703%40uwaterloo.ca.
For more options, visit https://groups.google.com/d/optout.