> mengx / nielsenmedia.com writes: > # > > # > I have to admit `filter' is not a best name; some proposed `collect!', > # > but I don't feel it's not collecting anything. > # > > # > > # > matz. > # > # Would convert/convert! or transform/transform! be better that > collect/filter? > # Of course they could mean something like "to_s", but in iterator context, > # I will not be confused. > > Well, filter once kind of made a sort of idiosyncratic sense in the distant > past when it was a semi-common UNIX idiom for something like a > sed/awk/nroff stage in a pipeline. filter also makes sense to anyone who's used any language other than smalltalk that has this function (except perl, of course, which uses 'grep' apparently in an attempt to confuse shell programmers). Uh, the non-destructive version, I mean (that ruby calles `detect'). I think ruby's use of filter is non-intuitive and potentially dangerous for everyone other than smalltalkers. However, even though I too prefer map, I think collect isn't so bad, and it's certainly not going anywhere. I would also highly discourage convert, transform, or other non-standard not-invented-here stuff (smalltalk has a sort of excuse of being old :) What's wrong with collect! ? It makes sense to me: a.sort -> `a' sorted a.sort! -> `a' sorted and modifies `a' to the same value a.flatten -> `a' with interior sequences eliminated a.flatten! -> `a' with interior sequences eliminated, and modifies `a' to the same value a.compact -> a.detect {|e| e != nil} a.compact! -> a.detect {|e| e != nil}, and modifies `a' to the same value It's not a huge leap for a programmer to imagine: a.collect -> `a' with function applied a.collect! -> `a' with function applied, and modifies `a' to the same value (or map/map!, which is, after all, The Standard) then we could also have: a.filter -> elts of `a' that are true for function a.filter! -> elts of `a' that are true for function, and modifies `a' to the same value Notice a certain consistency? *Most* of the standard methods have nice behavior here: given a method `foo' I don't have to look in the docs to know what `foo!' will do. That's a big win, I think. I'm sure the current definition of filter has some use somewhere, but I can't think of it, especially seeing how it's destructive. I think something like buf.concat(@attr.filter {|v| CGI::escape(v) }.join("&")) like you see in the stdlib would be much clearer as @attr = @attr.collect{|v| CGI::escpae(v) } buf.concat(@attr.join("&")) anyway, since user filter can obscure the fact that @attr is being modified. And for things like values = values.split('&').filter{|v| CGI::unescape(v) } filter is unnecessary. Actually, 9 out of 12 uses of filter in the stdlib are things like `foo = foo.filter' or `foo = bar.split.filter' which looks like people don't understand the usage of filter (I don't blame 'em). And then you have things like `foo(bar).filter' which look real dangerous to me because you don't know if foo() is returning a reference to an existing object or making a new one. While we're on the subject, what would a ruby implementation of foldr look like? Is there one? foldr f (x:xs) = f x (foldr f xs) foldr f x = x foldr f [] = error "can't fold empty list with no initial value" class Array def foldr if self.length == 0 then raise ValueError, "can't fold empty list with no initial value" elsif self.length == 2 yield self[0], self[1] else yield self[0], self[1..-1].foldr end end end Hmm, that won't work... how do you use a recursive iterator? Probably you don't... I'm not thinking properly in ruby today :)