Jump to page: 1 2
Thread overview
[grammar] ambiguity on parenthized clauses
Apr 28, 2005
Manfred Nowak
Apr 28, 2005
Walter
Apr 28, 2005
Manfred Nowak
Apr 29, 2005
Walter
Apr 29, 2005
Manfred Nowak
Apr 29, 2005
Stewart Gordon
Apr 29, 2005
Manfred Nowak
May 03, 2005
Stewart Gordon
May 03, 2005
Manfred Nowak
May 03, 2005
Stewart Gordon
May 04, 2005
Manfred Nowak
May 04, 2005
Derek Parnell
May 04, 2005
Stewart Gordon
April 28, 2005
The `debug' and `synchronized' statements both have the options to
be followed immediately by a statement
  `synchronized stmt'
or have a parenthesed item between the keyword and the statement
  `synchronized( expr ) stmt'.

Because a statement can derive to an expression statement
consisting of an expression that starts with a left parenthesis
  `(*(new int))* *y;'
there is an ambiguity introduced if such a statement is turned into
a `synchronized' statement
  `synchronized (*(new int))* *y;'

In fact the current dmd resolves this ambiguity in favor of
  `synchronized( expr ) stmt'
by implementing the rules
  `synchronized stmtThatDoesNotStartWithLeftParenthesis'
  `synchronized ( expr ) stmt'

So there are at least three choices:

1. Holding up the status quo, which means that some statements are
not synchronizable
2. Requiring an empty pair of parenthesis between the keyword and
the statement
   `synchronized ( ) stmt'
   `synchronized ( expr ) stmt'
3. Changing the parentheses to something else
   `synchronized stmt'
   `synchronized !( expr ) stmt'

Similar arguments hold for the debug statement.

-manfred
April 28, 2005
"Manfred Nowak" <svv1999@hotmail.com> wrote in message news:d4qdg2$eij$1@digitaldaemon.com...
> The `debug' and `synchronized' statements both have the options to
> be followed immediately by a statement
>   `synchronized stmt'
> or have a parenthesed item between the keyword and the statement
>   `synchronized( expr ) stmt'.
>
> Because a statement can derive to an expression statement
> consisting of an expression that starts with a left parenthesis
>   `(*(new int))* *y;'
> there is an ambiguity introduced if such a statement is turned into
> a `synchronized' statement
>   `synchronized (*(new int))* *y;'
>
> In fact the current dmd resolves this ambiguity in favor of
>   `synchronized( expr ) stmt'
> by implementing the rules
>   `synchronized stmtThatDoesNotStartWithLeftParenthesis'
>   `synchronized ( expr ) stmt'
>
> So there are at least three choices:
>
> 1. Holding up the status quo, which means that some statements are not synchronizable

I agree it is ambiguous, but statements that start with ( are generally
contrived as the () are redundant. The example you gave can also be written
as:
    *(new int) * *y;
with no change in meaning. So option (1) works.


April 28, 2005
"Walter" <newshound@digitalmars.com> wrote:

[...]
> statements that start with ( are generally contrived as the ()
> are redundant.

May I remind on the fact that the evaluation order of expressions in general is not specified. Therefore one might very well be forced to introduce parentheses. And I do not think, that in `( a + b) * c' the parentheses are truly redundandent.

> The example you gave can also be written as:
>     *(new int) * *y;
> with no change in meaning. So option (1) works.

Agreed, if there are no overloads. One can always rewrite the statement by turning it into a blockstatement. However, the drawnback of option (1) is, that forgetting the need to rewrite may introduce subtle errors. Again the probability is extremely low because the contents of the clauses must meet semantic constraints.

However, is this suitable for a language which' design goal is to shield the programmer from unnecessary bugs?

-manfred
April 29, 2005
"Manfred Nowak" <svv1999@hotmail.com> wrote in message news:d4rfg7$1lme$1@digitaldaemon.com...
> "Walter" <newshound@digitalmars.com> wrote:
> > statements that start with ( are generally contrived as the ()
> > are redundant.
> May I remind on the fact that the evaluation order of expressions in general is not specified. Therefore one might very well be forced to introduce parentheses. And I do not think, that in `( a + b) * c' the parentheses are truly redundandent.

Correct, they aren't redundant in that case, but the expression also has no effect and so one would not see:

    debug (a + b) * c;

Furthermore, the argument to debug must be either an identifier or an integer literal. Anything else will give a syntax error. The argument to synchronize must resolve to an object reference. Add these up, and the chances are remote that there'd be any confusion not caught at compile time.


April 29, 2005
Manfred Nowak wrote:
<snip>
> 1. Holding up the status quo, which means that some statements are not synchronizable
<snip>

What is there to stop you from doing

    synchronized { (*(new int))* *y; }

?  Besides that this code would be a complete nop?

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.
April 29, 2005
Stewart Gordon <smjg_1998@yahoo.com> wrote:

> What is there to stop you from doing
> 
>      synchronized { (*(new int))* *y; }
> 
> ?  Besides that this code would be a complete nop?

Thanks for the confirmation of my posting http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/3836 where I already mentioned the possibility to wrap each statement by a blockstatement.

However, have a look at our own docs:

<cite href="http://www.digitalmars.com/d/expression.html#NewExpression">

There is an ambiguity in the grammar, however. Consider:
		(foo) - p;

Is this a cast of a dereference of negated p to type foo, or is it
p being subtracted from foo?
</cite>

Do you agree that the fact that there _is_ an ambiguity can serve as an argument against a language?

And both of your arguments hold here too:
1. The statement _can_ be rewritten as
           (foo / 1) - p
to make clear that a cast is not wanted.
2. This staement in C is doubtless a NOOP in both possible
interpretations.

However in D this might be an OP because the operators are overloadable and therefore may have side effects. Can you prove, that this argument does not hold?
April 29, 2005
"Walter" <newshound@digitalmars.com> wrote:

[...]
> Correct, they aren't redundant in that case, but the expression also has no effect and so one would not see:
> 
>     debug (a + b) * c;

ICNR.
<code>
import std.stdio;

class Int{
  Int opAdd(Int p){
    writef("Paradise");
    return new Int;
  }
  void opAdd(Object* P){
   writefln("Forget what I just wrote!");
  }
  Object* opMul(Object* p){
   writefln(" turned into hell. Red alert!");
   return null;}
}
void main(){
  Int x=new Int,y=new Int;
  Object o;
  Object* z= &o;
  synchronized (x + y) * z;
}
</code>

[...]
> Add these up, and the chances are remote that there'd be any confusion not caught at compile time.

Agreed. But it really took not much time to construct the example above.

-manfred
May 03, 2005
Manfred Nowak wrote:
<snip>
> However, have a look at our own docs:
> 
> <cite href="http://www.digitalmars.com/d/expression.html#NewExpression">
> 
> There is an ambiguity in the grammar, however. Consider: 		(foo) - p;
> 	
> Is this a cast of a dereference of negated p to type foo, or is it p being subtracted from foo?
> </cite>

If you had bothered to read what you just quoted, you would've noticed that it's talking about C(++) there.  And that this isn't part of the NewExpression section.

> Do you agree that the fact that there _is_ an ambiguity can serve as an argument against a language?
> 
> And both of your arguments hold here too:
> 1. The statement _can_ be rewritten as            (foo / 1) - p
> to make clear that a cast is not wanted.
<snip>

This has been completely unnecessary since DMD 0.119.

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.
May 03, 2005
Stewart Gordon <smjg_1998@yahoo.com> wrote:

[...]
> If you had bothered to read
[...]

Hey, Stewart. We are now getting into troubles because the limitations of this medium!

I know very well, that the example referenced is talking on C(++).

All I wanted to say is, that Walter himself uses the pure existence of an ambiguity in C(++) as an argument against C(++).

So, if he is not too self contained, after the above he also _must_ use the pure existence of an ambiguity in D as an argument against D.

Once more: all I want to express is that by prepending the synchronized keyword before a statement nobody would expect that the semantic of that statement may change. That is the same thing as with the preepnding of a cast: a cast is also not expected to change the semantic value of the expression casted.

So if D prevents the programmer from unforseeable bugs by introducing a syntactical element for casts, the kywaord `cast', to eliminate this ambiguity, it is reasonable to prevent every programmer from this ambiguity introduced by the specs of D itself also.

As a fourth possibilty I would reclaim, that the synchronized keyword must be followed by a blockstatement directly or after the parenthized clause.

-manfred

May 03, 2005
Manfred Nowak wrote:
<snip>
> I know very well, that the example referenced is talking on C(++).
> 
> All I wanted to say is, that Walter himself uses the pure existence of an ambiguity in C(++) as an argument against C(++).

Yes.  In as far as it's a weakness of these languages, but I wouldn't consider it as telling anyone "don't use C(++)".

> So, if he is not too self contained, after the above he also _must_ use the pure existence of an ambiguity in D as an argument against D.
<snip>

Some people do admit that their creations aren't perfect.  And since this particular imperfection doesn't exist in current D, this section doesn't have to influence when/where Walter admits it.

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.
« First   ‹ Prev
1 2