From: "Aleksi Niemelä" Date: 2000-07-06T19:25:04+02:00 Subject: [ruby-talk:03882] Re: Array.uniq! returning nil > |look too strange, confusing, or cryptic. Maybe just @, $, %, &. > > Other noise characters? Come on. ;-) Right! No more unnecessary noise! > Currently I feel no need for self-modifying, non-conditional > combination. I appreciate your feelings! It's great to hear about them. They reflect the design ideas of the language. > Basicly one should use copying (non-bang) version of the > methods. Why's that so? I mean it's a nice policy, but then we should be using it as consistenly (and much) as possible. But that's not good for performance. How about the opposite policy? For me the self-modifying, non-conditional combination is the thing I'm using most of the time. Most of my code is non-conditional by nature. Most of my code is also self-modifying as much as possible, rather than copying -- of course one copies things quite a lot, but I feel it should be done only when necessary. So maybe I should regard my code being non-unnecessarily-copying. a = "foo" b = a.split.uniq!.size # I don't say b = a.dup.split.dup.uniq.size If I want to copy things, I can make my point clear with dup. Afterall, it's much easier to say dup when needed (a.dup.action!) than to make something happen in-place with automatically copying routines. Anyway, I don't care about this so much. I can easily adapt to code in a way Ruby wants. Here I just feel Ruby has not made clear decision. If the policy is 'Ruby forces you to split your self-modifying non-conditional statements to multiple lines' I wonder why easiness was promoted for blocks. As far as I can see: a = ["fo", "ha"].collect do |txt| txt+"r" end should have been (forced and) coded as addR = proc do |txt| txt+"r" end a = ["fo", "ha"].collect(addR) In the latter example the self-modifying part is splitted. Actually the latter version might be better anyway, it's just that I love when I *can* code like the upper one, *and* when I'm not forced to code like the latter. Even then I might code it as latter. :) Well, my strongest argument is yet to come. If the difference between method and method! would be just the fact the latter modifies in-place, it'd be: 1) easy to learn 2) easy to remember 3) and most of all, very easy to make performance changes to the existing code The last point is important because with the current way you may end up hitting yourself when optimizing bigger source base. This example is made up, for dna-library: def apply_big_sequence(big) analysis = Feature.new(uniq).big.uniq.map do |feat| Feature.calc(feat) end analysis.use(big) 2**big.length end create_other_features( apply_big_sequence("CGAC")) Then we notice this is too slow because the return value of 'big' is *really big* and hardly fits our memory, so we choose to lose the copy-by-default. This version doesn't work: analysis = Feature.new(uniq).big.uniq!.map! do |feat| Feature.calc(feat) end so we have to remember to split up: def apply_big_sequence(big) big = Feature.new(uniq).big analysis = (big.uniq! || big).map! do |feat| Feature.calc(feat) end analysis.use(big) 2**big.length end but whoops, now we override our initial reference to big, which is supposed to be used later. And suddenly the change from dup.self_modify! to plain self_modify! has caused the need for a large code change (not just '!'), one additional and rarely-used idiom, and one additional variable. I think this is acceptable, in most other languages you can't do as much with as little coding. This is just a little bit akward when compared to the rest of the language design. If we continue on the current track, we have to be really careful in all documentation, to announce method! to be self-modifying-conditional most of the time (instead of previously informed simply self-modifying). - Aleksi