From: Robert Klemme Date: 2009-06-15T15:30:04+09:00 Subject: Re: each by arity On 15.06.2009 07:44, Joshua Ballanco wrote: > On Jun 14, 2009, at 9:22 PM, trans wrote: > >> >> On Jun 14, 4:43 pm, Yossef Mendelssohn wrote: >>> On Jun 14, 3:32 pm, Tony Arcieri wrote: >>> >>> >>> >>>> On Sun, Jun 14, 2009 at 1:37 PM, Joel VanderWerf >>>> wrote: >>>>> What would it do with >>>>> [ [1,2], [3,4] ].each {|x,y| ... } >>>> One iteration, with: >>>> x = [1,2] >>>> y = [3,4] >>>> This could be expanded out with: >>>> [ [1,2], [3,4] ].each {|(a,b),(c,d)| ... } >>>> and >>>> [ [1,2], [3,4] ].each {|(x,y)| ... } >>>> still provides the old behavior. >>> And by "the old behavior" I presume you mean two iterations: >>> >>> x = 1 >>> y = 2 >>> >>> x = 3 >>> y = 4 >>> >>> And how is that going to happen based on inspecting arity? At least >>> with 1.8.6, Proc.new {|x, y| } and Proc.new {|(x, y)| } both have an >>> arity of 2. >> The underlying systems has to see the difference regardless. In fact >> the current implementation has to do more, b/c it has to look at the >> receiver itself and see that it contains arrays as elements in order >> to know how to treat it, which is rather inefficient. (Also, I think >> one could argue that either this arity is wrong, or the concept of >> arity needs to be expanded with an added dimension.) But the problem is that we have two steps here: 1. invocation of yield 2. distributing arguments across block parameters If I followed the thread properly then step 1 would have to be influenced by knowledge about the block while currently only step 2 does. The code invoking yield needs to be in charge yet at the moment it only has arity as information. I believe more information about the block needs to be provided otherwise this cannot work because #each needs to know this or else it cannot decide how many elements from the current Enumerable must be handed off to the block. > At this point, it sounds more like we're talking about OCaml style > pattern matching than proc arity. I, for one, would love to see Ruby > gain some sort of pattern matching to work with elements, but I fear > this would be difficult to implement on top of Ruby's dynamism. 1.9 is actually moving into that direction: irb(main):001:0> f = lambda {|a,*b,c| p a,b,c} => # irb(main):002:0> f[1,2] 1 [] 2 => [1, [], 2] irb(main):003:0> f[1,2,3] 1 [2] 3 => [1, [2], 3] irb(main):004:0> f[1,2,3,4] 1 [2, 3] 4 => [1, [2, 3], 4] irb(main):005:0> And even in 1.8 you had some level of pattern matching, e.g. irb(main):001:0> h={1=>2,3=>4} => {1=>2, 3=>4} irb(main):002:0> h.inject(0) {|s,(k,v)| s + k + v} => 10 Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/