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/0FB7FA46-5D42-4F75-8B2E-804E74EEF9BF%40gmail.com. For more options, visit https://groups.google.com/d/optout.
