digitalmars.D.bugs - [grammar] ambiguity on parenthized clauses
- Manfred Nowak (28/28) Apr 28 2005 The `debug' and `synchronized' statements both have the options to
- Walter (7/26) Apr 28 2005 I agree it is ambiguous, but statements that start with ( are generally
- Manfred Nowak (14/19) Apr 28 2005 May I remind on the fact that the evaluation order of expressions in
- Walter (9/16) Apr 28 2005 Correct, they aren't redundant in that case, but the expression also has...
- Manfred Nowak (28/34) Apr 29 2005 ICNR.
-
Stewart Gordon
(10/12)
Apr 29 2005
- Manfred Nowak (25/30) Apr 29 2005 Thanks for the confirmation of my posting
- Stewart Gordon (11/29) May 03 2005 If you had bothered to read what you just quoted, you would've noticed
- Manfred Nowak (25/26) May 03 2005 [...]
- Stewart Gordon (12/19) May 03 2005 Yes. In as far as it's a weakness of these languages, but I wouldn't
- Manfred Nowak (8/11) May 03 2005 I'm giving up. I am not talking of the cast ambiguity of C(++) is
- Derek Parnell (15/29) May 03 2005 If it helps, Manfred, I understood your concerns. And your proposed
- Stewart Gordon (28/44) May 04 2005 Sorry if I misunderstood. We must have been talking at cross purposes
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
Apr 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 synchronizableI 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.
Apr 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
Apr 28 2005
"Manfred Nowak" <svv1999 hotmail.com> wrote in message news:d4rfg7$1lme$1 digitaldaemon.com..."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; 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.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.
Apr 28 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
Apr 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.
Apr 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?
Apr 29 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.
May 03 2005
Stewart Gordon <smjg_1998 yahoo.com> wrote: [...]And since this particular imperfection doesn't exist in current D, this section doesn't have to influence when/where Walter admits it.I'm giving up. I am not talking of the cast ambiguity of C(++) is existing in D, but an ambiguity on the synchronized/debug statement. But now it seems hopeless to me, that only a gloom of understanding will enlighten your horizont. Thanks for your patience. -manfred
May 03 2005
On Wed, 4 May 2005 00:19:33 +0000 (UTC), Manfred Nowak wrote:Stewart Gordon <smjg_1998 yahoo.com> wrote: [...]If it helps, Manfred, I understood your concerns. And your proposed solutions were reasonable too. There does exist an ambiguity in the language. With the 'debug', as Walter points out, it probably doesn't matter because bad expressions could be caught at compile time. With the synchronized statement, as you point out, ambiguities can be resolved by placing the 'target' statement inside braces. So in the end, I guess it would not be a high priority need to address these ambiguities prior to v1.0 -- Derek Parnell Melbourne, Australia http://www.dsource.org/projects/build/ v2.05 released 02/May/2005 http://www.prowiki.org/wiki4d/wiki.cgi?FrontPage 4/05/2005 10:36:58 AMAnd since this particular imperfection doesn't exist in current D, this section doesn't have to influence when/where Walter admits it.I'm giving up. I am not talking of the cast ambiguity of C(++) is existing in D, but an ambiguity on the synchronized/debug statement. But now it seems hopeless to me, that only a gloom of understanding will enlighten your horizont. Thanks for your patience.
May 03 2005
Derek Parnell wrote:On Wed, 4 May 2005 00:19:33 +0000 (UTC), Manfred Nowak wrote:<snip>Sorry if I misunderstood. We must have been talking at cross purposes from the moment the C(++) cast ambiguity was mentioned on the thread.I'm giving up. I am not talking of the cast ambiguity of C(++) is existing in D, but an ambiguity on the synchronized/debug statement.I suppose it's OK for some ambiguities to be resolved by "if it's parseable as X, it's X, otherwise it's Y" rules. In these cases, X would be synchronized ( Expression ) Statement debug ( IntegerLiteral ) Statement debug ( Identifier ) Statement which would make synchronized (qwert) - yuiop; equivalent to synchronized (qwert) { -yuiop; } but synchronized (qwert) / yuiop; equivalent to synchronized { (qwert) / yuiop; } Is this how DMD behaves at the moment? Or does it simply fail once it's tried to parse / yuiop; as a statement?But now it seems hopeless to me, that only a gloom of understanding will enlighten your horizont. Thanks for your patience.If it helps, Manfred, I understood your concerns. And your proposed solutions were reasonable too. There does exist an ambiguity in the language. With the 'debug', as Walter points out, it probably doesn't matter because bad expressions could be caught at compile time.With the synchronized statement, as you point out, ambiguities can be resolved by placing the 'target' statement inside braces. So in the end, I guess it would not be a high priority need to address these ambiguities prior to v1.0I still consider this case worth doing something about: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/1955 (see followups for how it could be resolved) Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
May 04 2005