wdte icon indicating copy to clipboard operation
wdte copied to clipboard

std/stream: new module for dealing with streams of elements

Open DeedleFake opened this issue 8 years ago • 0 comments

Streams should be able to do all of the normal stream/iterator type things, not just map.

  • [x] filter. This will probably require booleans.
  • [x] concat.
  • [x] flatMap.
  • [x] anyMatch.
  • [x] allMatch.
  • [ ] findFirst. (This might not be necessary, as it's kind of similar to anyMatch.)
  • [x] reduce.
  • [x] fold. Same thing as reduce but uses the first value of the stream as the initial value instead of getting one from the user. In other words, it's the same thing as -> s.reduce <next value of stream> r.
  • [ ] ~~sort.~~ Not really necessary, thanks to arrays.sort. It would have to do a collect first anyways, so just do -> s.collect -> a.sort -> a.stream to do the same thing explicitly.
  • [ ] unique. (This will require #4.)
  • [x] repeat. Repeats the entire stream infinitely. This will obviously require some buffering.
  • [x] limit. Stops the stream after the specified number of items. Might stop earlier if there are less items available. Combined with repeat could be used for, for example, repeating a string.
  • [ ] join. Similar to collect, but creates a string instead of an array and separates things with a delimiter. Might want to remove strings.join since you could do the same thing with a.stream array -> s.join delimiter. Not exactly sure how it should work if the elements of the stream aren't strings, but it's probably fine to just assume they are and require the user to use a map to turn them into strings manually first. Of course, this, and collect for that matter, can also be done with reduce fairly easily.
  • [x] zip. Takes two or more streams and returns a new stream that returns arrays of each element. If one stream ends before the others then end will get inserted into the array where the next element would have been. In other words, zip s1 s2 will yield [<next element from s1>; <next element from s2>], and so on.
  • [ ] inspect. Similar to map but doesn't change the value being yielded. It's kind of like sticking an ignored chain element into the middle of the stream, since you can't actually just ignore the map. That doesn't work.
  • [x] skip. Returns a stream that skips the specified number of elements from the underlying stream.
  • [ ] step. Returns a stream that yields every nth element from the underlying stream.
  • [ ] reverse. Returns a stream that starts at the end of the given stream. Only works on streams that are reversible, which will also have to be implemented. Things like streams of array elements and some string-based streams should probably work with this.
  • [x] min and max. Takes a number and a comparison function and returns that many of either the minimum or maximum values yielded by the stream as an array, sorted in ascending or descending order, respectively.
  • [ ] chain. Calls the elements of the stream as if they're a chain.
  • [x] new. Takes a function that produces stream values. Combining this with flatMap should make it possible to make middle streams, although map will probably be easier to use most of the time. Edit: This is significantly less useful than I expected due to the obvious fact that everything is immutable in this language. Right. Duh. It could still be useful for creating a stream over incoming data, however, but something like io.lines is more likely to be useful for that.
  • [x] end. A special value that indicates that a stream created with new is done. It's essentially the same as a Go implementation of Next() returning nil, false.

~~forEach is not necessary, as it's basically the same as a void map.~~ Added drain to make it possible to use map as a foreach without doing the allocation that collect does.

DeedleFake avatar May 11 '17 15:05 DeedleFake