Feature #8361

Alternative syntax for block parameter

Added by Alexey Muranov about 3 years ago. Updated almost 3 years ago.



I propose an alternative syntax for block parameters:

p = lambda [x] {
# do whatever you like with x here, but be sure to return the result

instead of

p = lambda { |x|
# ...

This would be consistent with the syntax of procedure call: (({p[a]})).

Also, compare:

a_bunch.each [element] do
# ...


a_bunch.each do |element|
# ...



#1 [ruby-core:54750] Updated by Nobuyoshi Nakada about 3 years ago

If it were introduced, how could you pass an array with a block?

#2 [ruby-core:54751] Updated by Nobuyoshi Nakada about 3 years ago

  • Category set to syntax
  • Status changed from Open to Feedback

#3 [ruby-core:54753] Updated by Alexey Muranov about 3 years ago

You are right, there is a problem. It is similar to the problem with hashes:

def f(h); end
f {1=>2}
# => SyntaxError: unexpected =>, expecting '}'

It can be worked around in the same way:

foo([1, 2, 3]) [x] {x*x}

But there will be incompatibilities.
I will think more about it.

P.S. The problem appears only if the array is the first argument, otherwise it would be clear because of the absence of comma.

#4 Updated by Alexey Muranov about 3 years ago

From the top of my mind, i can propose only this:

p = lambda [x]->{
# ...

[2, 3, 4].map [x]->{x*x}.reduce [0, 1] [m, o]->{m << o}

(i didn't like the new lambda syntax anyway:) ).

Another possibility:

p = lambda [x]:{
# ...

collection.each [element] : do
# ...

[2, 3, 4].map [x]:{x*x}.reduce([0, 1]) [m, o]:{m << o}

(This might conflict with the ternary expression.)

The current syntax for comparison:

[2, 3, 4].map {|x| x*x}.reduce([0, 1]) {|m, o| m << o}

#5 [ruby-core:54759] Updated by Nobuyoshi Nakada about 3 years ago

It's unacceptable to distinguish two semantics of "(({[ ]}))" by a token following ((after)) it.

#6 [ruby-core:54760] Updated by Yukihiro Matsumoto about 3 years ago

I don't think the syntax cannot be defined without conflict.
Prove me I am wrong.


#7 [ruby-core:54764] Updated by Alexey Muranov about 3 years ago

I agree, it is getting complicated, maybe it was a bad idea. It may be closed if you do not think it is worth consideration.

The best i could think of was to allow to use some symbol, the colon for example, to separate explicitly the block from the list of argument:

p = lambda : [x] {
# ...

collection.each : [element] do
# ...

But it is getting complicated and not very readable.

#8 [ruby-core:54774] Updated by Nobuyoshi Nakada about 3 years ago

It conflicts with ternary expressions, and symbol literals.

You should abandon use of colon and brackets.

#9 [ruby-core:54778] Updated by Alexey Muranov about 3 years ago

Nobu: i do not think the conflict with ternary expression is the worst part: i think that if in ambiguous cases the colon was interpreted as a part of ternary expression, there would be no conflict with existing code.

It was probably the choice of words (({each})) and (({do})) that bothered me. (({each})) sounds more like a name of a quantifier that should be followed by parameter names, than like a name of a method.

After all, in method definitions the list of parameters is not separated from the body either:

def foo(x) x*x end

proc do |x| x*x end

#10 [ruby-core:55094] Updated by Alexey Muranov almost 3 years ago

I do not mind this being closed, i do not see how this can be made consistent with the existing syntax, and probably my reason for suggesting this was not valid, but as a side note, i want to mention that i have just discovered that in Combinatory Logic, when a lambda term from Lambda Calculus is converted to an equivalent combinatorial term, an alternative intermediate notation used sometimes for "(({λx.M}))" is "(({[x].M}))":

#11 [ruby-core:55240] Updated by Zachary Scott almost 3 years ago

  • Status changed from Feedback to Closed


Also available in: Atom PDF