Florian Growrote: > Yukihiro Matsumoto wrote about new lambda syntaxes: > >> |f = ->(a) { ... } >> >> [...] >> >> |f = { : a,b=1|2 : ... } >> |f = { : * : ... } # equivalent to f = lambda { ... } >> >> Unfortunately :+space causes conflicts as well. > > > I'm probably not in the position to criticize, but I still feel like I > have to or I will regret not having done it later. > > Is it really in accordance to Ruby's design mentality to introduce new > syntax just because parsing the most obvious one is too complex? > > This is how I understand the issue. A new syntax is being considered > because this will be hard to get working: > > l = lambda { |x, y, z = (x | y)| ... } > > And because block arguments don't look much (and aren't handled much > like) method arguments. > > If this is not only for the above two reasons, but also because you > think that the above sample is hard to parse visually then please > consider other choices that are more obvious than arrows pointing into > random directions: > > f = def(x, y, z = x | y) { ... } # also need to allow def x() { ... } > f = fun(x, y, z = x | y) { ... } # a new keyword I find this the most unified looking, similar to JavaScript's function() {}. > Personally, I think this complete situation is not as much as a problem > as it might appear. -- Blocks are a special syntax in Ruby and we have > all gotten used to it. It is okay for them to also have a special > argument syntax. Having default arguments with the current one is not > hard. We don't need both method call semantics and special block > semantics both at the same time. We could get rid of Proc.new without > losing anything but the danger of confusion. > > Sure, the C#, Perl and ECMAScript way of doing this has advantages like > being able to assign closures to variables with the same syntax as with > method calls. It also allows multiple closures per method and storing > them in hashes without a second syntax. Should we switch to it? Should > this have been the way for Ruby to do it since the beginning? > > As stated above I think switching might be more trouble than its worth. > Sure, if you learn Ruby you will at one point try to do "x = { exit }", > but after a small surprise you will have learnt to insert the "lambda". > > Now to the more difficult part. Would it have been better if Ruby would > have merged blocks and lambdas since the beginning? This is hard to > answer. When I was learning Ruby I thought that it would be great to be > able to supply multiple blocks to one method without needing a different > syntax. Has this been a limitation? Nope, but that could be related to > users of languages automatically working around issues before they > encounter them. > > So would there have been a downside to Ruby having unified blocks and > lambdas since the beginning? Yes, I think that > > 10.upto(20, { |i| puts i }) > > is harder to type and read than > > 10.upto(20) { |i| puts i } > > One can now argue that it does not matter for cases where there only is > a block: > > 1.times { } is the same as 1.times({ }) anyway. > > Or that we could allow trailing arguments that happen to be blocks to > appear outside of the argument list: > > Array.new(5) { |i| i * 2 } == Array.new(5, { |i| i * 2 }) > > # It is hard to come up with methods that take multiple blocks which > # isn't very surprising. > ary.context_each( > first: { |i| puts "First: #{i}" }, > last: { |i| puts "Last: #{i}" }, > ) { |i| puts i } > > # Or: > ary.context_each( > first: { |i| puts "First: #{i}" }, > last: { |i| puts "Last: #{i}" }, > middle: { |i| puts i } > ) > > I also think that you might be able to fix the arrow syntax by moving > it. I think something like this is acceptable: > > adder = (a, b) -> { a + b } Could you remove the -> entirely? Then an anonymous function is *exactly that*. :) f = (a, b) { a + b } > And perhaps: > > printer = a -> { puts a } > > And even more perhaps: > > printer = a -> puts a > > This is again very hard to parse. Perhaps even for humans. So: > > adder = \(a, b) -> { a + b } > printer = \a -> { puts a } So, basically Haskell? :) Forgive me for hardly ever posting to Ruby, I just like to watch. > Don't get me wrong here. It might be rare, but in this case I am not > actually trying to talk you into changing the language. I think the best > and least risky option is to just keep the current situation. I am > usually for sacrificing backwards compatibility to gain more > intuitiveness and simplicity, but in this case the problem is not big > enough to solve it (yet?). Mike A.