Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is '[f x[1]]' ungrammatical while '[1 + x[1]]' is?

Tags:

syntax

ruby

For an Array x, the following are grammatical expressions:

  • puts x[1]
  • [puts(x[1])]
  • [1 + x[1]]

but this:

  • [puts x[1]]

fails to parse with:

syntax error, unexpected tIDENTIFIER, expecting keyword_do or '{' or '('

Why can't the parser figure out this syntax?

like image 642
vladpisanov Avatar asked Nov 14 '17 19:11

vladpisanov


Video Answer


2 Answers

I believe this parsing behavior is intentional--not a bug. It's an unfortunate side-effect of Ruby allowing omitted parentheses. This code is, of course, fine:

def f x, y=0
  x + y
end

f 2    # 2
f 2, 3 # 5

But what is the result of this code?

[f 2, 3]

[2,3] or [5]? In order for the syntactical analyzer to handle this code, it would need to understand the arity of the method. But because Ruby is dynamic that cannot be determined until the method call is actually performed.

Rather than allow the ambiguous case, which would surely result in surprising situations during runtime, the designers opted for the (still surprising, but) easily fixable error during parsing.

Note: you could still argue that in the case where it is the last element there is no ambiguity

[3, f 2]
# should be [3, 2]

but I can imagine pulling my hair out if Ruby let's me write that and then slaps me with a syntax error when I add one more element to the end of the array. I can understand the decision to simply not allow omitted parentheses inside arrays.

like image 50
Max Avatar answered Sep 19 '22 04:09

Max


In Ruby you can often, but not always omit the parentheses around method calls. You've found a case where you can't. Sometimes there's too much ambiguity for Ruby to understand exactly what you want and you must be more specific.

The valid notation here is:

[puts(x[1])]

Though as puts always returns nil, this is really an odd thing to do.

like image 30
tadman Avatar answered Sep 19 '22 04:09

tadman