[ruby-core:25709] [Bug #2131] f(not x) => syntax error

0 views
Skip to first unread message

James M. Lawrence

unread,
Sep 22, 2009, 8:50:17 AM9/22/09
to ruby...@ruby-lang.org
Bug #2131: f(not x) => syntax error
http://redmine.ruby-lang.org/issues/show/2131

Author: James M. Lawrence
Status: Open, Priority: Normal
Category: core
ruby -v: ruby 1.9.2dev (2009-09-22 trunk 25031) [i386-darwin9.6.0]

% patch -p0 < test_parse.patch
patching file test/ruby/test_parse.rb

% ./ruby -v -I./lib test/ruby/test_parse.rb
ruby 1.9.2dev (2009-09-22 trunk 25031) [i386-darwin9.6.0]
Loaded suite test/ruby/test_parse
Started
.....................................F.............
Finished in 0.029999 seconds.

1) Failure:
test_not_arg(TestParse) [test/ruby/test_parse.rb:833]:
Exception raised:
<#<SyntaxError: (eval):1: syntax error, unexpected tIDENTIFIER, expecting '('
f(not x)
^>>.

51 tests, 198 assertions, 1 failures, 0 errors, 0 skips


----------------------------------------
http://redmine.ruby-lang.org

Nobuyoshi Nakada

unread,
Sep 22, 2009, 9:03:14 AM9/22/09
to ruby...@ruby-lang.org
Issue #2131 has been updated by Nobuyoshi Nakada.

Status changed from Open to Rejected

`not' expression is a statement, and a statement can't be an argument without parentheses.
----------------------------------------
http://redmine.ruby-lang.org/issues/show/2131

----------------------------------------
http://redmine.ruby-lang.org

Caleb Clausen

unread,
Sep 22, 2009, 10:57:25 AM9/22/09
to ruby...@ruby-lang.org
Nobuyoshi Nakada wrote:
> `not' expression is a statement, and a statement can't be an argument without parentheses.

I've been aware for a long time that 'not', 'and', and 'or' are
disallowed directly inside method arguments, but I've never understood
the justification. Can someone please explain to me _why_ 'not' should
be treated differently than '!' in this context?

James M. Lawrence

unread,
Sep 22, 2009, 11:13:06 AM9/22/09
to ruby...@ruby-lang.org
Issue #2131 has been updated by James M. Lawrence.


This should have been classified as a feature request.

Since (not x) is legal syntax, it is my opinion that f(not x) should be legal.

Erik Scheirer

unread,
Sep 22, 2009, 8:56:25 PM9/22/09
to ruby...@ruby-lang.org
I agree.

Yukihiro Matsumoto

unread,
Sep 23, 2009, 5:26:44 AM9/23/09
to ruby...@ruby-lang.org
Hi,

In message "Re: [ruby-core:25713] [Bug #2131] f(not x) => syntax error"


on Wed, 23 Sep 2009 00:13:06 +0900, "James M. Lawrence" <red...@ruby-lang.org> writes:

|This should have been classified as a feature request.
|
|Since (not x) is legal syntax, it is my opinion that f(not x) should be legal.

So, do you mean a,b,c = 1,2,3 is legal syntax, should we allow
f(a,b,c = 1,2,3) ?

In fact, it's matter of precedence, kinda difficult to "fix".

matz.

Rick DeNatale

unread,
Sep 23, 2009, 12:17:38 PM9/23/09
to ruby...@ruby-lang.org
On Wed, Sep 23, 2009 at 5:26 AM, Yukihiro Matsumoto <ma...@ruby-lang.org> wrote:
> Hi,
>
> In message "Re: [ruby-core:25713] [Bug #2131] f(not x) => syntax error"
>    on Wed, 23 Sep 2009 00:13:06 +0900, "James M. Lawrence" <red...@ruby-lang.org> writes:
>
> |This should have been classified as a feature request.
> |
> |Since (not x) is legal syntax, it is my opinion that f(not x) should be legal.
>
> So, do you mean a,b,c = 1,2,3 is legal syntax, should we allow
> f(a,b,c = 1,2,3) ?

or even

f(class Foo;attr_accessor :bar;end;Foo.new.x=5)

<G>

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

Caleb Clausen

unread,
Sep 23, 2009, 12:51:46 PM9/23/09
to ruby...@ruby-lang.org

f(a,b,c=1,2,3) is actually legal, tho the commas are method parameter
commas, not multiple assignment commas.

I think I get it now; the precedence of comma is higher than that of
and/or/not, so the problem is not so much in parsing
f(x and y)
which should be straightforward, but more complicated related cases like
f(x and y,z)
which would parse somewhat like
f(x and (y,z))
which makes no sense. Ideally, one would like to have 'and' be higher
precedence than ',' in this particular case. Getting precedence
exceptions like that to work is tricky and ugly; I can understand now
why you'd rather avoid it. My own parser has the same issue with 'and'
and 'or'.

Curiously, tho, RedParse is able to parse
f(not x,y)
and
f(not x)
in exactly the way I (and the OP) expect; ',' is lower precedence than
'not'.


James M. Lawrence

unread,
Oct 5, 2009, 2:13:35 AM10/5/09
to ruby...@ruby-lang.org
Issue #2131 has been updated by James M. Lawrence.


09/23/2009 06:26 PM - Yukihiro Matsumoto:


>|This should have been classified as a feature request.
>|
>|Since (not x) is legal syntax, it is my opinion that f(not x) should be legal.
>
>So, do you mean a,b,c = 1,2,3 is legal syntax, should we allow
>f(a,b,c = 1,2,3) ?

That (a,b,c = 1,2,3) and f(a,b,c = 1,2,3) contain different meanings
inside the parens does not really affect my argument.

[0] + (a, b, c = 1, 2, 3) # => [0, 1, 2, 3]

Whether that should mean [0, a, b, 1, 2, 3] or something else is a
different matter.

My point is that the parens serve to disambiguate,

[0] + a, b, c = 1, 2, 3 # => syntax error
[0] + (a, b, c = 1, 2, 3) # => [0, 1, 2, 3]
[0] + f a, b, c = 1, 2, 3 # => syntax error
[0] + f(a, b, c = 1, 2, 3) # => ok

true | not false # => syntax error
true | (not false) # => true
true | f not false # => syntax error
true | f(not false) # => syntax error

Why should the last case fail? I also see no reason why

f(class Foo;attr_accessor :x;end;Foo.new.x=5) # => syntax error

should necessarily be illegal. It's just f(5) with a side-effect.
The parens are fully capable of capturing the expression.

I can understand ignoring this bug report because I have not provided
a backward-compatible parse.y which handles these cases.

That it was rejected immediately implies no such parse.y can exist, or
that if it did then we wouldn't want it. Which is it and why?

David A. Black

unread,
Oct 5, 2009, 6:23:41 AM10/5/09
to ruby...@ruby-lang.org
Hi --

One case that comes to mind is:

f(class Foo; attr_accessor :x; end; Foo.new.x = 5,6)

Is 6 a second argument to f, or a second argument to Foo#x= ?


David

--
David A. Black, Director
Ruby Power and Light, LLC (http://www.rubypal.com)
Ruby/Rails training, consulting, mentoring, code review
Book: The Well-Grounded Rubyist (http://www.manning.com/black2)

Yukihiro Matsumoto

unread,
Oct 5, 2009, 10:52:26 AM10/5/09
to ruby...@ruby-lang.org
Hi,

In message "Re: [ruby-core:25937] [Feature #2131] f(not x) => syntax error"


on Mon, 5 Oct 2009 15:13:35 +0900, "James M. Lawrence" <red...@ruby-lang.org> writes:

|My point is that the parens serve to disambiguate,
|
| [0] + a, b, c = 1, 2, 3 # => syntax error
| [0] + (a, b, c = 1, 2, 3) # => [0, 1, 2, 3]
| [0] + f a, b, c = 1, 2, 3 # => syntax error
| [0] + f(a, b, c = 1, 2, 3) # => ok

The last line is the point. Although it seems just parentheses around
a multiple assignment, it really is a sequence of arguments, in which
third actual argument is an assignment to local variable c. That
implies we have two usage of parentheses, one for expression grouping,
the other for method parameters. They are same characters, but they
serve different roles.

| true | not false # => syntax error
| true | (not false) # => true
| true | f not false # => syntax error
| true | f(not false) # => syntax error
|
|Why should the last case fail? I also see no reason why

In syntax rules, "not f a, b" is allowed, so that if we want to allow
the last case to be legal, the syntax must allow "f(not f a, b)" which
apparently an error.

| f(class Foo;attr_accessor :x;end;Foo.new.x=5) # => syntax error
|
|should necessarily be illegal. It's just f(5) with a side-effect.
|The parens are fully capable of capturing the expression.

I think you're confusing parentheses for grouping and parentheses for
arguments.

matz.

James M. Lawrence

unread,
Oct 6, 2009, 9:13:29 AM10/6/09
to ruby...@ruby-lang.org
Issue #2131 has been updated by James M. Lawrence.


Yukihiro Matsumoto:


>I think you're confusing parentheses for grouping and parentheses for
>arguments.

The portion you clipped from my previous post shows that I understood
("...different meanings inside the parens..."). Again, the change in
meaning does not affect my point.

Given that I am still being misunderstood (apparently by everyone), I
will restate like this: parens have the absolute power to disambiguate
any and all cases. When someone writes (1 + 2)*3, he is overriding
the "natural order" of precedence in order to express what he wants.

To be stepwise explicit, consider a parser that upon encountering "f("
pushes the token '(' onto a stack whose size is now n. The only
condition which marks the end of f's arguments is the token ')' at
level n. Arguments are separated by the ',' token at level n, (and
this is key) _even_ if the meaning inside the parens changes as a
result.

It's the explicitness of the parens which bestows the ability to
override the "natural" syntax rules. (1 + 2)*3 has a different
meaning than 1 + 2*3 (a different situation, but the principle is the
same).

David Black:


>
> f(class Foo; attr_accessor :x; end; Foo.new.x = 5,6)
>
>Is 6 a second argument to f, or a second argument to Foo#x= ?

Not a problem at all -- split commas at the same level of the parens.
6 is a second argument to f. Any commas which may appear inside
'class Foo...end' are at a higher stack level and are thus not
considered.

Returning to the clipped part of my comment:


> That (a,b,c = 1,2,3) and f(a,b,c = 1,2,3) contain different meanings
> inside the parens does not really affect my argument.
>

> [0] + (a, b, c = 1, 2, 3) # => [0, 1, 2, 3]
>

> Whether that should mean [0, a, b, 1, 2, 3] or something else is a
> different matter.

That is, whether or not Python-like tuples deserve consideration is a
different matter. It is _already_ the case that <expression> inside
(<expression>) can take on a different meaning when it appears as
f(<expression>).

And it is already the case that f <expression> is not interchangeable
with f(<expression>).

Ultimately it comes back to f(not x). It feels obvious to me that it
should work as a result of the explicit parens. I would be surprised
if no backward-compatible parsing scheme is possible which includes
this case (not necessarily one based upon the toy strategy described
above).

Yukihiro Matsumoto

unread,
Oct 6, 2009, 9:54:47 AM10/6/09
to ruby...@ruby-lang.org
Hi,

In message "Re: [ruby-core:25968] [Feature #2131] f(not x) => syntax error"


on Tue, 6 Oct 2009 22:13:29 +0900, "James M. Lawrence" <red...@ruby-lang.org> writes:

|The portion you clipped from my previous post shows that I understood
|("...different meanings inside the parens..."). Again, the change in
|meaning does not affect my point.

<snip>

I am not sure I understand your statement. They are different. How
that big difference does not affect your point?

Anyway, I have just tried to add a new syntax rule to make f(not x)
work as you've requested. The naive addition cause 54 shift/reduce
conflicts. That means either I misunderstand your statement, or your
statement was ambiguous, or your sought syntax cannot be done by yacc
parser (so that we have to move to new parser, that moving must be
huge task and cause lot of potential incompatibility).

If someone come up with concrete syntax rules, I'd re-consider.

matz.

Michal Suchanek

unread,
Oct 6, 2009, 11:24:55 AM10/6/09
to ruby...@ruby-lang.org
2009/9/23 Rick DeNatale <rick.d...@gmail.com>:

> On Wed, Sep 23, 2009 at 5:26 AM, Yukihiro Matsumoto <ma...@ruby-lang.org> wrote:
>> Hi,
>>
>> In message "Re: [ruby-core:25713] [Bug #2131] f(not x) => syntax error"
>>    on Wed, 23 Sep 2009 00:13:06 +0900, "James M. Lawrence" <red...@ruby-lang.org> writes:
>>
>> |This should have been classified as a feature request.
>> |
>> |Since (not x) is legal syntax, it is my opinion that f(not x) should be legal.
>>
>> So, do you mean a,b,c = 1,2,3 is legal syntax, should we allow
>> f(a,b,c = 1,2,3) ?

Well, it's somewhat ambiguous in this case. Comma is used both as
argument separator and as assignment separator. Spicing with more
parens should help, though.

>
> or even
>
>  f(class Foo;attr_accessor :bar;end;Foo.new.x=5)
>
> <G>
>

It's not legal syntax? That surprises me .. it does return a value, doesn't it?

Well, maybe adding that Foo.new.x=5 is a bit overboard.

Thanks

Michal

James M. Lawrence

unread,
Oct 6, 2009, 7:21:27 PM10/6/09
to ruby...@ruby-lang.org
Issue #2131 has been updated by James M. Lawrence.


matz:


> I am not sure I understand your statement. They are different. How
> that big difference does not affect your point?

Because it is already the case that <expression> can have a different


meaning when it appears as f(<expression>).

You gave a good example. The thing inside parens here:

[0] + (a,b,c = 1,2,3)

means something different than the thing inside parens here:

[0] + f(a,b,c = 1,2,3)

Both are valid Ruby syntax.

If there is an objection to the way this behaves, it does not affect
my point because the behavior is already there. It is already the
case that given some code in parens, placing a method call in front
can change the meaning of that code. This feature request would not
introduce it.

I think it boils down to letting method-call parens capture everything
contained by them while giving commas the lowest precedence inside.

Yukihiro Matsumoto

unread,
Oct 6, 2009, 8:08:34 PM10/6/09
to ruby...@ruby-lang.org
Hi,

In message "Re: [ruby-core:25977] [Feature #2131] f(not x) => syntax error"


on Wed, 7 Oct 2009 08:21:27 +0900, "James M. Lawrence" <red...@ruby-lang.org> writes:

|I think it boils down to letting method-call parens capture everything
|contained by them while giving commas the lowest precedence inside.

As far as I could, it was not possible without introducing syntax
incompatibility, or throwing away the current parser as a whole.
I'd love to be proven wrong.

matz.

Reply all
Reply to author
Forward
0 new messages