www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - The empty statement ";" - when is it useful?

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
D has ";" as the empty statement. In fact I think it's an empty 
declaration because it can appear at top level.

When is it any good? The only place I can think of is after a label

blah: ;

But then you can always say

blah: {}

which is arguably less puzzling. Any other places?


Andrei
Jul 25 2009
next sibling parent reply Don <nospam nospam.com> writes:
Andrei Alexandrescu wrote:
 D has ";" as the empty statement. In fact I think it's an empty 
 declaration because it can appear at top level.
 
 When is it any good? The only place I can think of is after a label
 
 blah: ;
 
 But then you can always say
 
 blah: {}

Except in an asm block. Can't think of anything else.
 
 which is arguably less puzzling. Any other places?
 
 
 Andrei

Jul 25 2009
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Don wrote:
 Andrei Alexandrescu wrote:

 blah: {}

Except in an asm block. Can't think of anything else.

But an asm block doesn't contain D statements, so that's another matter. Stewart.
Jul 26 2009
parent Don <nospam nospam.com> writes:
Stewart Gordon wrote:
 Don wrote:
 Andrei Alexandrescu wrote:

 blah: {}

Except in an asm block. Can't think of anything else.

But an asm block doesn't contain D statements, so that's another matter. Stewart.

only exists in D, is copied from the D syntax, and which is actually odd and a bit annoying. (It's particularly annoying in the case where the next line is a version statement).
Jul 28 2009
prev sibling next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
Andrei Alexandrescu wrote:
 D has ";" as the empty statement. In fact I think it's an empty 
 declaration because it can appear at top level.
 
 When is it any good? The only place I can think of is after a label
 
 blah: ;
 
 But then you can always say
 
 blah: {}
 
 which is arguably less puzzling. Any other places?
 
 
 Andrei

for (; cond; inc) { ... } or as the result of a string mixin?
Jul 25 2009
next sibling parent reply BCS <none anon.com> writes:
Hello KennyTM~,

 Andrei Alexandrescu wrote:
 
 D has ";" as the empty statement. In fact I think it's an empty
 declaration because it can appear at top level.
 
 When is it any good? The only place I can think of is after a label
 
 blah: ;
 
 But then you can always say
 
 blah: {}
 
 which is arguably less puzzling. Any other places?
 
 Andrei
 


for({} false; 42) {}
 
 or as the result of a string mixin?
 

Jul 25 2009
parent Robert Fraser <fraserofthenight gmail.com> writes:
BCS wrote:
 for({} false; 42) {}

Eww...
Jul 26 2009
prev sibling next sibling parent Patrick Kreft <patrick_kreft gmx.net> writes:
KennyTM~ Wrote:

 for (; cond; inc) { ... }

for ( init ; cond; inc ) ... init and inc are in the most programming language deducible to empty, but the resulting ';' isnt a empty statement so this us legal code: void main(string[] args) { for(;false;) { } }
Jul 25 2009
prev sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
KennyTM~ wrote:
<snip>
 for (; cond; inc) { ... }

ForStatement: for (Initialize Test; Increment) ScopeStatement Initialize: ; NoScopeNonEmptyStatement a syntactic form in its own right, so irrelevant to the general case of ; as a statement. Stewart.
Jul 26 2009
prev sibling next sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Andrei Alexandrescu wrote:
 D has ";" as the empty statement. In fact I think it's an empty 
 declaration because it can appear at top level.

That's always been one of my peeves. At least, ever since I discovered that preventing such common C typos as if (...); { ... } isn't implemented by disallowing ";" as a statement altogether, even though at the time there was nothing in the spec to _allow_ it. http://d.puremagic.com/issues/show_bug.cgi?id=327 Walter once claimed that it's useful for automatically generated code. Though I'm still not quite sure how. Stewart.
Jul 26 2009
next sibling parent reply Don <nospam nospam.com> writes:
Stewart Gordon wrote:
 Andrei Alexandrescu wrote:
 D has ";" as the empty statement. In fact I think it's an empty 
 declaration because it can appear at top level.

That's always been one of my peeves. At least, ever since I discovered that preventing such common C typos as if (...); { ... } isn't implemented by disallowing ";" as a statement altogether, even though at the time there was nothing in the spec to _allow_ it. http://d.puremagic.com/issues/show_bug.cgi?id=327 Walter once claimed that it's useful for automatically generated code. Though I'm still not quite sure how.

Yes. He's recently the claimed the same thing about the comma operator, but I don't buy that argument. I've never needed to use either of them myself. (In the case of comma, sure it works as a sequence point when you have: a,b, return a; but it doesn't work for a,b, return b; which is 50% of the cases. I think it's a fallacious argument). Interestingly CommaExpression doesn't seem to be defined anywhere in the D spec.
 
 Stewart.

Jul 28 2009
next sibling parent reply Christian Kamm <kamm-incasoftware removethis.de> writes:
Don wrote:
 Interestingly
 CommaExpression doesn't seem to be defined anywhere in the D spec.

It's under the heading of 'Expression': http://www.digitalmars.com/d/2.0/expression.html#Expression
Jul 28 2009
parent Don <nospam nospam.com> writes:
Christian Kamm wrote:
 Don wrote:
 Interestingly
 CommaExpression doesn't seem to be defined anywhere in the D spec.

It's under the heading of 'Expression': http://www.digitalmars.com/d/2.0/expression.html#Expression

Jul 28 2009
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Bill Baxter wrote:
 On Tue, Jul 28, 2009 at 12:09 AM, Don<nospam nospam.com> wrote:
 Walter once claimed that it's useful for automatically generated code.
 Though I'm still not quite sure how.

I don't buy that argument. I've never needed to use either of them myself. (In the case of comma, sure it works as a sequence point when you have: a,b, return a; but it doesn't work for a,b, return b; which is 50% of the cases. I think it's a fallacious argument). Interestingly CommaExpression doesn't seem to be defined anywhere in the D spec.

You meant to say it doesn't work for a,b, return a; right? And I don't think that would be 50% of the cases. a,b,return b seems much more common. But either way the argument is ridiculous. It doesn't need to be as basic an operator as a single comma just for the sake of making code generation easier.

I agree. Walter also mentioned the code generation argument in a conversation with me, fully expecting something like "hell yeah" from me, but was disappointed :o). If he were right and the comma operator would be a net win for better code generation, it would be a net win for better handwritten code. But it's not for either; it is some win, but minor. Anyway, if I had my way I'd eliminate the empty statement ";". It's just uselessly hanging in there. It adds half a page total to TDPL just because I must first define it and then explain for all of if, while, switch, for, foreach... that they can't control an empty statement. If the empty statement didn't exist in the first place, I wouldn't be wasting readers' time. BTW, the use of ";" in foreach is not a problem; that use could be easily defined as sheer punctuation. Andrei
Jul 28 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Andrei Alexandrescu wrote:
 Bill Baxter wrote:
 On Tue, Jul 28, 2009 at 12:09 AM, Don<nospam nospam.com> wrote:
 Walter once claimed that it's useful for automatically generated code.
 Though I'm still not quite sure how.

operator, but I don't buy that argument. I've never needed to use either of them myself. (In the case of comma, sure it works as a sequence point when you have: a,b, return a; but it doesn't work for a,b, return b; which is 50% of the cases. I think it's a fallacious argument). Interestingly CommaExpression doesn't seem to be defined anywhere in the D spec.

You meant to say it doesn't work for a,b, return a; right? And I don't think that would be 50% of the cases. a,b,return b seems much more common. But either way the argument is ridiculous. It doesn't need to be as basic an operator as a single comma just for the sake of making code generation easier.

I agree. Walter also mentioned the code generation argument in a conversation with me, fully expecting something like "hell yeah" from me, but was disappointed :o). If he were right and the comma operator would be a net win for better code generation, it would be a net win for better handwritten code. But it's not for either; it is some win, but minor. Anyway, if I had my way I'd eliminate the empty statement ";". It's just uselessly hanging in there. It adds half a page total to TDPL just because I must first define it and then explain for all of if, while, switch, for, foreach... that they can't control an empty statement. If the empty statement didn't exist in the first place, I wouldn't be wasting readers' time. BTW, the use of ";" in foreach is not a problem; that use could be easily defined as sheer punctuation. Andrei

U comma(T,U)(T a, U b) { return b; } Is there any reason you couldn't use something like that?
Jul 28 2009
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Daniel Keep wrote:
 Andrei Alexandrescu wrote:
 Bill Baxter wrote:
 On Tue, Jul 28, 2009 at 12:09 AM, Don<nospam nospam.com> wrote:
 Walter once claimed that it's useful for automatically generated code.
 Though I'm still not quite sure how.

operator, but I don't buy that argument. I've never needed to use either of them myself. (In the case of comma, sure it works as a sequence point when you have: a,b, return a; but it doesn't work for a,b, return b; which is 50% of the cases. I think it's a fallacious argument). Interestingly CommaExpression doesn't seem to be defined anywhere in the D spec.

And I don't think that would be 50% of the cases. a,b,return b seems much more common. But either way the argument is ridiculous. It doesn't need to be as basic an operator as a single comma just for the sake of making code generation easier.

conversation with me, fully expecting something like "hell yeah" from me, but was disappointed :o). If he were right and the comma operator would be a net win for better code generation, it would be a net win for better handwritten code. But it's not for either; it is some win, but minor. Anyway, if I had my way I'd eliminate the empty statement ";". It's just uselessly hanging in there. It adds half a page total to TDPL just because I must first define it and then explain for all of if, while, switch, for, foreach... that they can't control an empty statement. If the empty statement didn't exist in the first place, I wouldn't be wasting readers' time. BTW, the use of ";" in foreach is not a problem; that use could be easily defined as sheer punctuation. Andrei

U comma(T,U)(T a, U b) { return b; } Is there any reason you couldn't use something like that?

Absolutely! And now that order of evaluation will be defined to be left-to-right in D, the semantics would be quite the same. Andrei
Jul 28 2009
prev sibling parent reply Arthur Lloyd <via google.com> writes:
Daniel Keep Wrote:

 U comma(T,U)(T a, U b) { return b; }
 
 Is there any reason you couldn't use something like that?

Sorry, this is probably a newbie question, but.. So instead of return a, b, c; you now have to write return comma(a, comma(b, c)); ? How will that help?
Jul 28 2009
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Arthur Lloyd wrote:
 Daniel Keep Wrote:
 
 U comma(T,U)(T a, U b) { return b; }

 Is there any reason you couldn't use something like that?

Sorry, this is probably a newbie question, but.. So instead of return a, b, c; you now have to write return comma(a, comma(b, c)); ? How will that help?

I think he just means that the comma operator is not a strategic advantage for automated code generation. Andrei
Jul 28 2009
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Jarrett Billingsley wrote:
  Tue, Jul 28, 2009 at 2:28 PM, Arthur Lloyd<via google.com> wrote:
 Daniel Keep Wrote:

 U comma(T,U)(T a, U b) { return b; }

 Is there any reason you couldn't use something like that?


typeof(T[$ - 1]) comma(T...)(T args) { return args[$ - 1]; } There. Now you can do "comma(a, b, c)".

Still won't solve the problem Andrei rightly pointed out. But this will: T[$-1] comma(T...)(lazy T args) { foreach (a; args[0..$-1]) cast(void) a; return args[$-1]; } Stewart.
Jul 28 2009
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Jarrett Billingsley wrote:
<snip>
 For two, what problem did Andrei point out?  Order of evaluation of
 function arguments?  On the contrary, he said "now that order of
 evaluation will be defined to be left-to-right in D, the semantics
 would be quite the same".  Your code is what you'd have to use in D1,
 but in D2, the simpler version would suffice.

What do you understand by the combination of "now" and "will be"? I understood that he was speaking either sarcastically or hypothetically. Or can you find any official statement of this change, let alone a rationale for it? Stewart.
Jul 28 2009
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Stewart Gordon wrote:
 Jarrett Billingsley wrote:
 <snip>
 For two, what problem did Andrei point out?  Order of evaluation of
 function arguments?  On the contrary, he said "now that order of
 evaluation will be defined to be left-to-right in D, the semantics
 would be quite the same".  Your code is what you'd have to use in D1,
 but in D2, the simpler version would suffice.

What do you understand by the combination of "now" and "will be"? I understood that he was speaking either sarcastically or hypothetically. Or can you find any official statement of this change, let alone a rationale for it?

No, sorry. Usually I strive to be precise, but this time I just wasn't. The plan is to define order of evaluation to be lexical order. Somehow I can't convince Walter that that means assignment too! e1[e2] = e3; means: 1. Evaluate e1 2. Evaluate e2 3. Evaluate [] 4. Evaluate e3 5. Evaluate assignment. Walter wants: 1. Evaluate e3. Why in the world, I have no idea. 2, 3. Evaluate e1 and e2, I'm not sure in which order he thinks is right 4. Evaluate [] 4. Evaluate = Lexical order rules. Lexical order dammit! Walter and I see eye to eye probably 95% of the time, which has two disadvantages: (a) everybody here thinks one is influencing the other when in fact most of the time we arrive at the same conclusion from very different paths, (b) the remaining 5% are disconcerting. This is one of those cases. Andrei
Jul 28 2009
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Andrei Alexandrescu wrote:
<snip>
 No, sorry. Usually I strive to be precise, but this time I just wasn't. 
 The plan is to define order of evaluation to be lexical order. Somehow I 
 can't convince Walter that that means assignment too!

I still would like to know where you found that plan! The decision to leave order of evaluation unspecified was a deliberate one at the time, and for good reasons. One of these reasons was to open the option of evaluating subexpressions in parallel. I'm not sure what the others were, but another optimisation potential that comes to my mind is to minimise the working memory while still allowing expressions to be written in an intuitive order. Who has decided that these reasons are no longer good, and why? Stewart.
Jul 29 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Stewart Gordon wrote:
 Andrei Alexandrescu wrote:
 <snip>
 No, sorry. Usually I strive to be precise, but this time I just 
 wasn't. The plan is to define order of evaluation to be lexical order. 
 Somehow I can't convince Walter that that means assignment too!

I still would like to know where you found that plan! The decision to leave order of evaluation unspecified was a deliberate one at the time, and for good reasons. One of these reasons was to open the option of evaluating subexpressions in parallel. I'm not sure what the others were, but another optimisation potential that comes to my mind is to minimise the working memory while still allowing expressions to be written in an intuitive order. Who has decided that these reasons are no longer good, and why?

This has been a source of long discussion in C++ circles, and Walter and I have also discussed the matter several times. Defining order of evaluation has good benefits, and the loss in efficiency has with time been reduced to just a few corner cases that don't seem to justify the cost anymore. Note that operations can still be evaluated in parallel as long as there's no dependencies between them. Andrei
Jul 29 2009
next sibling parent reply BCS <ao pathlink.com> writes:
Reply to Andrei,

 Stewart Gordon wrote:
 
 One of these reasons was to open the option of evaluating
 subexpressions in parallel.  I'm not sure what the others were, but
 another optimisation potential that comes to my mind is to minimise
 the working memory while still allowing expressions to be written in
 an intuitive order.
 
 Who has decided that these reasons are no longer good, and why?
 

Note that operations can still be evaluated in parallel as long as there's no dependencies between them. Andrei

You could go with "apparent order", that is the code can work anyway it wants as long as the end effect is the same as if the order was per the spec.
Jul 29 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
BCS wrote:
 Reply to Andrei,
 
 Stewart Gordon wrote:

 One of these reasons was to open the option of evaluating
 subexpressions in parallel.  I'm not sure what the others were, but
 another optimisation potential that comes to my mind is to minimise
 the working memory while still allowing expressions to be written in
 an intuitive order.

 Who has decided that these reasons are no longer good, and why?

Note that operations can still be evaluated in parallel as long as there's no dependencies between them. Andrei

You could go with "apparent order", that is the code can work anyway it wants as long as the end effect is the same as if the order was per the spec.

That's the plan. Andrei
Jul 29 2009
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Andrei Alexandrescu wrote:
<snip>
 This has been a source of long discussion in C++ circles, and Walter and 
 I have also discussed the matter several times. Defining order of 
 evaluation has good benefits, and the loss in efficiency has with time 
 been reduced to just a few corner cases that don't seem to justify the 
 cost anymore. Note that operations can still be evaluated in parallel as 
 long as there's no dependencies between them.

So the compiler would be allowed to parallelise only if it can determine that the two subexpressions don't depend on each other? This could get complicated when you consider calculations that are involved enough to be worth parallelising in the first place. Stewart.
Jul 29 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Stewart Gordon wrote:
 Andrei Alexandrescu wrote:
 <snip>
 This has been a source of long discussion in C++ circles, and Walter 
 and I have also discussed the matter several times. Defining order of 
 evaluation has good benefits, and the loss in efficiency has with time 
 been reduced to just a few corner cases that don't seem to justify the 
 cost anymore. Note that operations can still be evaluated in parallel 
 as long as there's no dependencies between them.

So the compiler would be allowed to parallelise only if it can determine that the two subexpressions don't depend on each other?

Yes.
 This could get 
 complicated when you consider calculations that are involved enough to 
 be worth parallelising in the first place.

Quite the contrary, in fact. Involved calculations in a given expression entail more often than not complicated operations as opposed to complicated updates. Andrei
Jul 29 2009
prev sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Jarrett Billingsley wrote:
 On Tue, Jul 28, 2009 at 7:46 PM, Stewart Gordon<smjg_1998 yahoo.com> wrote:

 Or can you find any official statement of this change, let alone a rationale
 for it?

http://www.digitalmars.com/d/archives/digitalmars/D/assignment_left-to-right_or_right-to-left_evaluation_89616.html That's the thread I remember it being discussed on.

In which Walter hasn't posted anything ... unless the archiver dropped it.
 Also, this is the second time your reply has broken threading, at
 least on the mailing list..

It hasn't broken threading as I view it in Thunderbird. It sounds to me like a bug in the mailing list. Is anybody else seeing this thread broken (other than through the web interface, where this is a known problem)? Stewart.
Jul 29 2009
prev sibling next sibling parent Don <nospam nospam.com> writes:
Bill Baxter wrote:
 On Tue, Jul 28, 2009 at 12:09 AM, Don<nospam nospam.com> wrote:
 Walter once claimed that it's useful for automatically generated code.
 Though I'm still not quite sure how.

I don't buy that argument. I've never needed to use either of them myself. (In the case of comma, sure it works as a sequence point when you have: a,b, return a; but it doesn't work for a,b, return b; which is 50% of the cases. I think it's a fallacious argument). Interestingly CommaExpression doesn't seem to be defined anywhere in the D spec.

You meant to say it doesn't work for a,b, return a; right?

 And I don't think that would be 50% of the cases.  a,b,return b seems
 much more common.

The only time I've considered using comma is with: assert(a); b = foo(a); assert(c); return b; But you're probably right, it's less than 50% of the time in practice.
 But either way the argument is ridiculous.  It doesn't need to be as
 basic an operator as a single comma just for the sake of making code
 generation easier.
 
 --bb

Jul 28 2009
prev sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Tue, Jul 28, 2009 at 7:46 PM, Stewart Gordon<smjg_1998 yahoo.com> wrote:
 Jarrett Billingsley wrote:
 <snip>
 For two, what problem did Andrei point out? =A0Order of evaluation of
 function arguments? =A0On the contrary, he said "now that order of
 evaluation will be defined to be left-to-right in D, the semantics
 would be quite the same". =A0Your code is what you'd have to use in D1,
 but in D2, the simpler version would suffice.

What do you understand by the combination of "now" and "will be"? I understood that he was speaking either sarcastically or hypothetically. Or can you find any official statement of this change, let alone a ration=

 for it?

 Stewart.

http://www.digitalmars.com/d/archives/digitalmars/D/assignment_left-to-righ= t_or_right-to-left_evaluation_89616.html That's the thread I remember it being discussed on. Also, this is the second time your reply has broken threading, at least on the mailing list..
Jul 28 2009
prev sibling next sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Tue, Jul 28, 2009 at 12:09 AM, Don<nospam nospam.com> wrote:
 Walter once claimed that it's useful for automatically generated code.
 Though I'm still not quite sure how.

Yes. He's recently the claimed the same thing about the comma operator, but I don't buy that argument. I've never needed to use either of them myself. (In the case of comma, sure it works as a sequence point when you have: a,b, return a; but it doesn't work for a,b, return b; which is 50% of the cases. I think it's a fallacious argument). Interestingly CommaExpression doesn't seem to be defined anywhere in the D spec.

You meant to say it doesn't work for a,b, return a; right? And I don't think that would be 50% of the cases. a,b,return b seems much more common. But either way the argument is ridiculous. It doesn't need to be as basic an operator as a single comma just for the sake of making code generation easier. --bb
Jul 28 2009
prev sibling next sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
 Tue, Jul 28, 2009 at 2:28 PM, Arthur Lloyd<via google.com> wrote:
 Daniel Keep Wrote:

 U comma(T,U)(T a, U b) { return b; }

 Is there any reason you couldn't use something like that?

Sorry, this is probably a newbie question, but.. So instead of return a, b, c; you now have to write return comma(a, comma(b, c)); ? How will that help?

typeof(T[$ - 1]) comma(T...)(T args) { return args[$ - 1]; } There. Now you can do "comma(a, b, c)".
Jul 28 2009
prev sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Tue, Jul 28, 2009 at 5:46 PM, Stewart Gordon<smjg_1998 yahoo.com> wrote:
 Jarrett Billingsley wrote:
 =A0Tue, Jul 28, 2009 at 2:28 PM, Arthur Lloyd<via google.com> wrote:
 Daniel Keep Wrote:

 U comma(T,U)(T a, U b) { return b; }

 Is there any reason you couldn't use something like that?

Sorry, this is probably a newbie question, but.. So instead of return a=



 b, c; you now have to write return comma(a, comma(b, c)); ? How will th=



 help?

typeof(T[$ - 1]) comma(T...)(T args) { return args[$ - 1]; } There. =A0Now you can do "comma(a, b, c)".

Still won't solve the problem Andrei rightly pointed out. =A0But this wil=

 T[$-1] comma(T...)(lazy T args) {
 =A0 =A0foreach (a; args[0..$-1]) cast(void) a;
 =A0 =A0return args[$-1];
 }

For one, that's almost verbatim what Tom S suggested in "comma expressions must die." For two, what problem did Andrei point out? Order of evaluation of function arguments? On the contrary, he said "now that order of evaluation will be defined to be left-to-right in D, the semantics would be quite the same". Your code is what you'd have to use in D1, but in D2, the simpler version would suffice.
Jul 28 2009
prev sibling parent Tim Matthews <tim.matthews7 gmail.com> writes:
On Sun, 26 Jul 2009 02:30:56 +0800
KennyTM~ <kennytm gmail.com> wrote:


 
 for (; cond; inc) { ... }
 

In c++: #define ever ;; for(ever) { ... }
Jul 27 2009