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

C4e88907313843cf07f6d85ba8162120?d=identicon&s=25 James M. Lawrence (Guest)
on 2009-09-23 00:07
(Received via mailing list)
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.

----------------------------------------
http://redmine.ruby-lang.org/issues/show/2131
1787805b8e0638cb0fb11a8dd24f1766?d=identicon&s=25 Erik Scheirer (Guest)
on 2009-09-23 02:56
(Received via mailing list)
I agree.
0ec4920185b657a03edf01fff96b4e9b?d=identicon&s=25 Yukihiro Matsumoto (Guest)
on 2009-09-23 11:26
(Received via mailing list)
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"
<redmine@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.
8f6f95c4bd64d5f10dfddfdcd03c19d6?d=identicon&s=25 Rick Denatale (rdenatale)
on 2009-09-23 18:17
(Received via mailing list)
On Wed, Sep 23, 2009 at 5:26 AM, Yukihiro Matsumoto <matz@ruby-lang.org>
wrote:
> 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
B6cd7ed5ace59d8694aa5cf9ef2e5142?d=identicon&s=25 Caleb Clausen (Guest)
on 2009-09-23 18:52
(Received via mailing list)
Yukihiro Matsumoto wrote:
> f(a,b,c = 1,2,3) ?
>
> In fact, it's matter of precedence, kinda difficult to "fix".

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'.
C4e88907313843cf07f6d85ba8162120?d=identicon&s=25 James M. Lawrence (Guest)
on 2009-10-05 08:49
(Received via mailing list)
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?

----------------------------------------
http://redmine.ruby-lang.org/issues/show/2131
F53b05cdbdf561cfe141f69b421244f3?d=identicon&s=25 David A. Black (Guest)
on 2009-10-05 12:24
(Received via mailing list)
Hi --

On Mon, 5 Oct 2009, James M. Lawrence wrote:

>
>  [0] + a, b, c = 1, 2, 3     # => syntax 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.

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
0ec4920185b657a03edf01fff96b4e9b?d=identicon&s=25 Yukihiro Matsumoto (Guest)
on 2009-10-05 16:52
(Received via mailing list)
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"
<redmine@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.
C4e88907313843cf07f6d85ba8162120?d=identicon&s=25 James M. Lawrence (Guest)
on 2009-10-06 15:14
(Received via mailing list)
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).

----------------------------------------
http://redmine.ruby-lang.org/issues/show/2131
0ec4920185b657a03edf01fff96b4e9b?d=identicon&s=25 Yukihiro Matsumoto (Guest)
on 2009-10-06 15:56
(Received via mailing list)
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"
<redmine@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.
F889bf17449ffbf62345d2b2d316a937?d=identicon&s=25 Michal Suchanek (Guest)
on 2009-10-06 17:25
(Received via mailing list)
2009/9/23 Rick DeNatale <rick.denatale@gmail.com>:
>> 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
C4e88907313843cf07f6d85ba8162120?d=identicon&s=25 James M. Lawrence (Guest)
on 2009-10-07 01:23
(Received via mailing list)
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.

----------------------------------------
http://redmine.ruby-lang.org/issues/show/2131
0ec4920185b657a03edf01fff96b4e9b?d=identicon&s=25 Yukihiro Matsumoto (Guest)
on 2009-10-07 02:09
(Received via mailing list)
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"
<redmine@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.
This topic is locked and can not be replied to.