On 10/5/05, Damian Conway <[EMAIL PROTECTED]> wrote: > Luke wrote: > > I'm just wondering why you feel that we need to be so careful. > > Because I can think of at least three reasonable and useful default behaviours > for zipping lists of differing lengths: > > # Minimal (stop at first exhausted list)... > for @names ¥ @addresses -> $name, $addr { > ... > } > > > # Maximal (insert undefs for exhausted lists)... > for @finishers ¥ (10..1 :by(-1)) -> $name, $score { > $score err next; > ... > } > > > # Congealed (ignore exhausted lists)... > for @queue1 ¥ @queue2 -> $server { > ... > } > > Which means that there will be people who expect each of those to *be* the > default behaviour for unbalanced lists.
Perhaps that makes sense. That certainly makes sense for other kinds of constructs. Something makes me think that this is a little different. Whenever somebody asks what "Y" is on #perl6, and I tell them that it interleaves two lists, a follow-up question is *always* "what does it do when the lists are unbalanced." Now, that may just be a behavior of #perl6ers, but I'm extrapolating. It means that there isn't an assumption, and if they weren't #perl6ers, they'd RTFM about it. When I learned Haskell and saw zip, I asked the very same question[1]. I was about as comfortable writing Haskell at that point as beginning programmers are with writing Perl, but it still took me about ten seconds to write a test program to find out. The rest of Perl doesn't trade a reasonable default behavior for an error, even if it *might* be surprising the first time you use it. It doesn't take people long to discover that kind of error and never make that mistake again. If we make zip return a list of tuples rather than an interleaved list, we could eliminate the final 1/3 of those errors above using the typechecker. That would make the for look like this: for @a Y @b -> ($a, $b) {...} An important property of that is the well-typedness of the construct. With the current zip semantics: my A @a; my B @b; for @a Y @b -> $a, $b { # $a has type A (+) B # $b has type A (+) B } With tuple: my A @a; my B @b; for @a Y @b -> ($a, $b) { # $a has type A # $b has type B } Which is more correct. No... it's just correct, no superlative needed. It also keeps things like this from happening: for @a Y @b -> $a, $b { say "$a ; $b" } # a1 b1 # a2 b2 # a3 b3 # ... "Oh, I need a count," says the user: for @a Y @b Y 0... -> $a, $b { # oops, forgot to add $index say "$a ; $b" } # a1 b1 # 0 a2 # b2 1 # ... Luke [1] But I didn't need to. The signature told me everything: zip :: [a] -> [b] -> [(a,b)] It *has* to stop at the shortest one, because it has no idea how to create a "b" unless I tell it one. If it took the longest, the signature would have looked like: zip :: [a] -> [b] -> [(Maybe a, Maybe b)] Anyway, that's just more of the usual Haskell praise.