On Mon, May 6, 2013 at 7:36 PM, Graydon Hoare <[email protected]> wrote:

> On 13-05-06 09:46 AM, Matthieu Monrocq wrote:
>
> > I would therefore propose:
> >
> > - zip: only on collections of equal length
> > - zipcut: stop iteration as soon as the shortest collection is exhausted
> > - zipfill: fill the "void" (somehow: default value, Option<T>, ...)
> >
> > This way we have all 3 variants, with descriptive names for those 2 who
> > introduce specific behavior.
>
> This seems to me exactly the sort of "customize how you continue in the
> face of a rare event that has multiple reasonable forms of recovery"
> that conditions are made for. Do you think they'd be appropriate?
>
> -Graydon
>
>
>
I am not so sure.


I was thinking a bit more how "zipfill" could be implemented but it's a
mess. You really have to choose between "default" (but not everything has
sensible defaults!) and Option<T> (but then you have to
pattern-match/dereference the Option every time). Option<T> seems better
(no magic value), but apart from the awkwardness it is also incompatible
with conditions: it changes the return type (unless zip systematically
return Options ? but that's crazy!).


And then I realized that "zipfill" can be expressed much more cleanly with
composition instead:

- zip(cycle(short), long) => cycle through short until long is exhausted,
needs a "stop"
- zip(cycle(short, long.size()), long) => cycle through short until
long.size() elements were served
- zip(fill(short, defval), long)
...


So maybe we could use conditions with a "zip" that is strict by default and
leaves it up to a condition to signal whether to "Stop" or "Fail" when one
list is too short. However there is the issue of "choosing" what that list
is, namely what if I want to "Stop" if the first list is too short, but
would rather "Fail" if it is the second ?

Furthermore, there is also the issue of the transitive behavior of
conditions. Since "zip" wraps arbitrary iterators, it might wrap an
iterator itself implemented in terms of "zip", and in this case the
"condition" set for the outer "zip" would also be used (unless cancelled)
by the inner "zip". I find it non-obvious. It might point at a more general
issue about (potentially) recursive functions and conditions by the way.


So, instead, maybe composition should be used for "zipcut" too. I can
imagine the "take" function of Haskell fitting neatly here:

- zip(short, take(long, short.size())) => only consider the first
"short.size()" elements of "long" (fails if long is not long enough thus!)

Though I find it difficult to catter to the case where one list is shorter
than the other, but we cannot know their sizes in advance (I am thinking
streams here).


In the end, I would favor having "zip" and "zipcut", and not using
conditions. But maybe that's me :)

-- Matthieu
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to