Why does `a + f b` not parse?

ruby-1.9.2-p0 > 2 + sqrt 5
SyntaxError: (irb):25: syntax error, unexpected tINTEGER, expecting
keyword_do or ‘{’ or ‘(’
from /home/martin/.rvm/rubies/ruby-1.9.2-p0/bin/irb:17:in `’

I can’t see why that doesn’t parse properly.

martin

On Tue, Oct 11, 2011 at 9:54 AM, Martin DeMello
[email protected]wrote:

ruby-1.9.2-p0 > 2 + sqrt 5
SyntaxError: (irb):25: syntax error, unexpected tINTEGER, expecting
keyword_do or ‘{’ or ‘(’
from /home/martin/.rvm/rubies/ruby-1.9.2-p0/bin/irb:17:in `’

I can’t see why that doesn’t parse properly.

In 1.8.7 I get the following:
irb(main):011:0> 2 + sqrt 5
SyntaxError: compile error
(irb):11: syntax error, unexpected tINTEGER, expecting kDO or ‘{’ or ‘(’
from (irb):11
from :0

but this one works

irb(main):014:0> 2 + Math.sqrt(5)
=> 4.23606797749979

On Oct 11, 2011, at 2:54 AM, Martin DeMello wrote:

ruby-1.9.2-p0 > 2 + sqrt 5
SyntaxError: (irb):25: syntax error, unexpected tINTEGER, expecting
keyword_do or ‘{’ or ‘(’
from /home/martin/.rvm/rubies/ruby-1.9.2-p0/bin/irb:17:in `’

I can’t see why that doesn’t parse properly.

martin

You have two options. First, you can tell ruby what library it needs to
load (in this case the Math library), or you can include it. You also
have to surround your number in parentheses ().

This means your code would either look like this:

ruby-1.9.2-p290 :004 > 2 + Math.sqrt(5)
=> 4.23606797749979

OR

ruby-1.9.2-p290 :005 > include Math
=> Object
ruby-1.9.2-p290 :006 > 2 + sqrt(5)
=> 4.23606797749979

Ironically, as somebody new to Ruby, I was just reading about Libraries
and Modules so your question was a good review for me. :wink:

Wayne

On Tue, Oct 11, 2011 at 06:32, Wayne B. [email protected]
wrote:

You also have to surround your number in parentheses ().

That’s the odd part. Just saying “sqrt 5” works (assuming you’ve
included Math, else “Math.sqrt 5”). But tack “2 +” on the front, and
suddenly Ruby can’t parse it any more, even though it has now more
of a clue that what’s coming is a mathematical expression.

-Dave

  • is a method that wants one parameter

2 + (Math.sqrt 5) works
2 + Math.sqrt(5) works
2 + Math.sqrt 5 works not

On Tue, Oct 11, 2011 at 1:02 PM, Dave A.
[email protected] wrote:

That’s the odd part. Just saying “sqrt 5” works (assuming you’ve
included Math, else “Math.sqrt 5”). But tack “2 +” on the front, and
suddenly Ruby can’t parse it any more, even though it has now more
of a clue that what’s coming is a mathematical expression.

Actually: No. As far as Ruby is concerned, you are chaining method
calls (remember: + is a method, not an operator!).

That this is a mathematical expression is coincidental

A (somewhat) contrived example:

“x 2”

Is that a method call (x(2)), or do you want to multiply 2 and x?


Phillip G.

gplus.to/phgaw | twitter.com/phgaw

A method of solution is perfect if we can forsee from the start,
and even prove, that following that method we shall attain our aim.
– Leibniz

Don’t top post, please.

2011/10/11 Bartosz Dziewoński [email protected]:

Yes, I think we all know that; the question is, why does 2 + sqrt(5)
parse, but 2 + sqrt 5 does not? I’ve been wondering this myself - is
that syntax somehow ambiguous?

So, which one shall it be?

2.+.sqrt(5)
2.+(sqrt(5))
2.+.sqrt.5
2.+(sqrt.5)
2.+(sqrt(5))


Phillip G.

gplus.to/phgaw | twitter.com/phgaw

A method of solution is perfect if we can forsee from the start,
and even prove, that following that method we shall attain our aim.
– Leibniz

Yes, I think we all know that; the question is, why does 2 + sqrt(5)
parse, but 2 + sqrt 5 does not? I’ve been wondering this myself - is
that syntax somehow ambiguous?

2011/10/11, jake kaiden [email protected]:

Phillip G. wrote in post #1026042:

(remember: + is a method, not an operator!)

That this is a mathematical expression is coincidental

this is a very important point in ruby… + is a method (and not an
operator, as Phillip pointed out,) that behaves differently with various
classes, including but not limited to Integers, Strings, and Arrays -
check out the following…

irb(main):001:0> p 2 + 5
7
=> nil
irb(main):002:0> p “two” + “five”
“twofive”
=> nil
irb(main):003:0> a1 = [“one”, “two”, “three”]
=> [“one”, “two”, “three”]
irb(main):004:0> a2 = [4, 5, 6]
=> [4, 5, 6]
irb(main):005:0> p a1 + a2
[“one”, “two”, “three”, 4, 5, 6]
=> nil

  • j

On Tue, Oct 11, 2011 at 4:33 PM, Phillip G.
[email protected] wrote:

2.+(sqrt(5))
2.+.sqrt.5
2.+(sqrt.5)
2.+(sqrt(5))

I believe the versions which turn a space into a dot are not valid
candidates. Or is there any place other than for operators where this
happens in Ruby? I mean “a b” can never by “a.b” but must always be
“a(b)”. That leaves only “2.+(sqrt(5))” on your list (item 2, same as
item 5).

It’s the same with ordinary methods:

$ ruby19 -ce ‘1 + f 2’
-e:1: syntax error, unexpected tINTEGER, expecting keyword_do or ‘{’ or
‘(’

$ ruby19 -ce ‘a.b c, d e’
-e:1: syntax error, unexpected tIDENTIFIER, expecting keyword_do or ‘{’
or ‘(’
$ ruby19 -ce ‘a.b c, d(e)’
Syntax OK

$ ruby19 -ce ‘a b, c d’
-e:1: syntax error, unexpected tIDENTIFIER, expecting keyword_do or ‘{’
or ‘(’
$ ruby19 -ce ‘a b, c(d)’
Syntax OK
16:48:16 oz-56838-negative-session-count$ ruby19 -ce ‘a.b c, d do end’
Syntax OK

I think as soon as the comma is missing the end of the argument list
or a nested argument list is expected by the parser (which is also
indicated by the error message).

Kind regards

robert

2011/10/11 Phillip G. [email protected]:

Don’t top post, please.

I was writing from my mobile, it was added automatically (I just don’t
have an oversized signature to brag about it). No, I do not have the
option to disable it. Don’t waste everybody’s time arguing about
top-posting when we’re both clearly posting on this list/forum
regularly and I clearly do not top post if I can.

2.+(sqrt.5)
2.+(sqrt(5))

All but one of these (which you actually repeated twice) are invalid
syntax. I think the parser isn’t quite that stupid, as it clearly
understands everything up to “5” (as we can see from the error
message), and only then barfs at what a human can understand as an
unparentesized argument to method call.

Please, try to make more sense when you’re being condescending.

– Matma R.

2011/10/11 Bartosz Dziewoński [email protected]:

All but one of these (which you actually repeated twice) are invalid
syntax.

?

That would mean that something like Class.instance_methods(:true).sort
wouldn’t work. We can chain as many methods as is possible, if we
like.

P.S.: When I’m condescending, you’ll know I’m condescending.


Phillip G.

gplus.to/phgaw | twitter.com/phgaw

A method of solution is perfect if we can forsee from the start,
and even prove, that following that method we shall attain our aim.
– Leibniz

On Oct 11, 2011, at 10:17 AM, Bartosz Dziewoński wrote:

Yes, I think we all know that; the question is, why does 2 + sqrt(5)
parse, but 2 + sqrt 5 does not? I’ve been wondering this myself - is
that syntax somehow ambiguous?

Bottom line is that operators have a higher precedence than argument
list construction.
Let’s rewrite the original code with parens showing this:

(2 + sqrt) 5

Two adjacent expressions with just white space between them is not
valid.
Thus the complaint about the unexpected integer.

For the original code to be interpreted meaningfully the parser would
have to prefer the following precedence:

2 + (sqrt 5)

which creates its own problems because now expressions can’t easily be
used in argument lists:

foo 3 + 4, 5

gets parsed as

(foo(3) + 4), 5

rather than

foo(3 + 4, 5)

Bottom line is that operators have a higher precedence than argument
list construction.

Gary W.

On Tue, Oct 11, 2011 at 9:08 PM, Phillip G.
[email protected] wrote:

On Tue, Oct 11, 2011 at 4:50 PM, Robert K.
[email protected] wrote:

I mean “a b” can never by “a.b” but must always be
“a(b)”. That leaves only “2.+(sqrt(5))” on your list (item 2, same as
item 5).

What about 2.+(2)? It’s equivalent to 2 + 2, after all, and not 2(+(2)).

That’s a different case because there is an operator between the
expressions. My statement only referred to non operator tokens
because for operators there always is an equivalent method form.
Sorry for not being more explicit about it.

“never” is a strong word to use, especially in Ruby. :wink:

Even in Ruby syntax there are some hard decisions made.

Cheers

robert

On Tue, Oct 11, 2011 at 4:50 PM, Robert K.
[email protected] wrote:

I mean “a b” can never by “a.b” but must always be
“a(b)”. That leaves only “2.+(sqrt(5))” on your list (item 2, same as
item 5).

What about 2.+(2)? It’s equivalent to 2 + 2, after all, and not 2(+(2)).

“never” is a strong word to use, especially in Ruby. :wink:


Phillip G.

gplus.to/phgaw | twitter.com/phgaw

A method of solution is perfect if we can forsee from the start,
and even prove, that following that method we shall attain our aim.
– Leibniz

On Tue, Oct 11, 2011 at 9:14 PM, Phillip G.
[email protected] wrote:

2011/10/11 Bartosz Dziewoński [email protected]:

All but one of these (which you actually repeated twice) are invalid
syntax.

?

That would mean that something like Class.instance_methods(:true).sort
wouldn’t work. We can chain as many methods as is possible, if we
like.

Yes, but spaces do not become dots except those before an operator.
Those forms in your list are not valid transformations of the input.
When considering how to group with brackets it only makes sense to
consider variants which could be created from the original.

Kind regards

robert

On Tue, Oct 11, 2011 at 10:08 PM, Robert K.
[email protected] wrote:

Yes, but spaces do not become dots except those before an operator.

Except that Ruby doesn’t have operators. , -, *, ** are all methods.
Granted, they get special treatment, but it’s syntactic sugar so that
they look like operators.


Phillip G.

gplus.to/phgaw | twitter.com/phgaw

A method of solution is perfect if we can forsee from the start,
and even prove, that following that method we shall attain our aim.
– Leibniz

Phillip G. wrote in post #1026187:

On Tue, Oct 11, 2011 at 10:08 PM, Robert K.
[email protected] wrote:

Yes, but spaces do not become dots except those before an operator.

Except that Ruby doesn’t have operators. , -, *, ** are all methods.
Granted, they get special treatment, but it’s syntactic sugar so that
they look like operators.

From the point of view of the parser, they are operators. From the point
of view of execution, they are method calls.

The statement “spaces do not become dots except those before an
operator” is not how it works. The expression is parsed just as in any
other language:

   expr
  / | \
 a  +  b

and from this a syntax tree is built equivalent to a.send(:+, b), and
then that’s what’s executed.

The reason that a + f b doesn’t parse is explained at
http://www.ruby-forum.com/topic/2762669#1026142

It’s because it parses as (a + f) b. And if the parsing precedence were
changed so it became a + (f b), then other undesirable behaviour would
result.