Forum: Ruby why does `a + f b` not parse?

Ae16cb4f6d78e485b04ce1e821592ae5?d=identicon&s=25 Martin DeMello (Guest)
on 2011-10-11 09:55
(Received via mailing list)
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 `<main>'

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

martin
Bfa153a37248515bbf6d7a7bd49ba171?d=identicon&s=25 J-H Johansen (Guest)
on 2011-10-11 11:19
(Received via mailing list)
On Tue, Oct 11, 2011 at 9:54 AM, Martin DeMello
<martindemello@gmail.com>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 `<main>'
>
> 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
0fadf2fbc6df2bc870fc88aab874b9c9?d=identicon&s=25 Wayne Brissette (Guest)
on 2011-10-11 12:33
(Received via mailing list)
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 `<main>'
>
> 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. ;)

Wayne
F141ba99f29e55f02207f5488fe5ce95?d=identicon&s=25 Dave Aronson (Guest)
on 2011-10-11 13:03
(Received via mailing list)
On Tue, Oct 11, 2011 at 06:32, Wayne Brissette <waynefb@earthlink.net>
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
D9ebdcb66f1583378e6f72155db507e2?d=identicon&s=25 Hans Mackowiak (hanmac)
on 2011-10-11 13:10
+ is a method that wants one parameter

2 + (Math.sqrt 5) works
2 + Math.sqrt(5) works
2 + Math.sqrt 5 works not
A70c94da27a322b077742779f62ef81d?d=identicon&s=25 Phillip Gawlowski (Guest)
on 2011-10-11 13:15
(Received via mailing list)
On Tue, Oct 11, 2011 at 1:02 PM, Dave Aronson
<rubytalk2dave@davearonson.com> 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 Gawlowski

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
5e3ddca8ea910cea06245c7b3c38007a?d=identicon&s=25 jake kaiden (lljk)
on 2011-10-11 13:52
Phillip Gawlowski 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
39093dd2b68b68960fecd0fe2b9a5045?d=identicon&s=25 Bartosz Dziewoński (matmarex)
on 2011-10-11 16:17
(Received via mailing list)
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 <jakekaiden@yahoo.com>:
A70c94da27a322b077742779f62ef81d?d=identicon&s=25 Phillip Gawlowski (Guest)
on 2011-10-11 16:33
(Received via mailing list)
Don't top post, please.

2011/10/11 Bartosz Dziewoński <matma.rex@gmail.com>:
> 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 Gawlowski

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
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (robert_k78)
on 2011-10-11 16:50
(Received via mailing list)
On Tue, Oct 11, 2011 at 4:33 PM, Phillip Gawlowski
<cmdjackryan@gmail.com> 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
39093dd2b68b68960fecd0fe2b9a5045?d=identicon&s=25 Bartosz Dziewoński (matmarex)
on 2011-10-11 19:53
(Received via mailing list)
2011/10/11 Phillip Gawlowski <cmdjackryan@gmail.com>:
> 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 Rex
A70c94da27a322b077742779f62ef81d?d=identicon&s=25 Phillip Gawlowski (Guest)
on 2011-10-11 21:08
(Received via mailing list)
On Tue, Oct 11, 2011 at 4:50 PM, Robert Klemme
<shortcutter@googlemail.com> 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. ;)

--
Phillip Gawlowski

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
A70c94da27a322b077742779f62ef81d?d=identicon&s=25 Phillip Gawlowski (Guest)
on 2011-10-11 21:15
(Received via mailing list)
2011/10/11 Bartosz Dziewoński <matma.rex@gmail.com>:
>
> 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 Gawlowski

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
E7559e558ececa67c40f452483b9ac8c?d=identicon&s=25 Gary Wright (Guest)
on 2011-10-11 21:51
(Received via mailing list)
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 Wright
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (robert_k78)
on 2011-10-11 22:06
(Received via mailing list)
On Tue, Oct 11, 2011 at 9:08 PM, Phillip Gawlowski
<cmdjackryan@gmail.com> wrote:
> On Tue, Oct 11, 2011 at 4:50 PM, Robert Klemme
> <shortcutter@googlemail.com> 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. ;)

Even in Ruby syntax there are some hard decisions made.

Cheers

robert
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (robert_k78)
on 2011-10-11 22:09
(Received via mailing list)
On Tue, Oct 11, 2011 at 9:14 PM, Phillip Gawlowski
<cmdjackryan@gmail.com> wrote:
> 2011/10/11 Bartosz Dziewoński <matma.rex@gmail.com>:
>>
>> 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
A70c94da27a322b077742779f62ef81d?d=identicon&s=25 Phillip Gawlowski (Guest)
on 2011-10-12 04:56
(Received via mailing list)
On Tue, Oct 11, 2011 at 10:08 PM, Robert Klemme
<shortcutter@googlemail.com> 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 Gawlowski

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
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2011-10-12 09:55
Phillip Gawlowski wrote in post #1026187:
> On Tue, Oct 11, 2011 at 10:08 PM, Robert Klemme
> <shortcutter@googlemail.com> 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.
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.