www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Killing the comma operator

reply Mathias Lang <mathias.lang sociomantic.com> writes:
If you were attending DConf2016, or watched Ali (excellent) talk 
[1] at some point, you probably remember this piece of code:

`synchronized (lockA, lockB)`

As documented in TDPL (thanks  schveiguy) [2].
Unfortunately, as someone pointed out, this isn't implemented, 
but still compile "thanks" to the comma operator [3].

There are many reasons to hate this almost invisible false friend.
One more example is returning a string containing a comma to mix 
it in. If you're not familiar enough with the language, you'll 
end up wondering why it isn't behaving as expected [4].
But there can be situations where it's useful. For example the 
following code isn't rare:

`for (; !a.empty && !b.empty; a.popFront, b.popFront) { /* Do 
stuff with ranges */ }`

Rewriting this wouldn't look as nice.

So, following DConf2016, I raised a P.R. to deprecate usage of 
the comma expressions, except within `for` loops increment [5].
The feedback we already got from druntime / phobos was pretty 
good: out of three occurrences in druntime, one was a bug [7]. 
Not a single message was triggered in Phobos, since it's using 
Dscanner, which is warning against it in assignments and 
(nowadays) synchronized [6].

It seems there is a reasonable ground to kill it. However, there 
have been legitimated concern about code breakage, so we would 
like to hear from other people:

Do you like comma expressions, and think its presence in the 
language is more pro than con ?


[1]: http://www.ustream.tv/recorded/86352137/highlight/699197
[2]: 
http://www.informit.com/articles/article.aspx?p=1609144&seqNum=15
[3]: 
https://github.com/dlang/dmd/blob/81cb1c8a6a4d594bd17bfc8e263b72ed72ff8cf3/src/parse.d#L5662-L5683
[4]: https://issues.dlang.org/show_bug.cgi?id=15993
[5]: https://github.com/dlang/dmd/pull/5737
[6]: 
https://github.com/Hackerpilot/Dscanner/blob/02f8f3c423a413d0f90e9d4698a2db9049e35b44/src/analysis/comma_expression.d
[7]: https://github.com/dlang/druntime/pull/1562
May 10 2016
next sibling parent reply Guillaume Piolat <contact gam3sfrommars.fr> writes:
On Tuesday, 10 May 2016 at 09:52:07 UTC, Mathias Lang wrote:
 It seems there is a reasonable ground to kill it. However, 
 there have been legitimated concern about code breakage, so we 
 would like to hear from other people:
With all due restraint and care for breakage, I'd say to take the appropriate response: KILL IT NOW, WITH FIRE This isn't even an annoying code breakage, it's one that has an obvious, backward-compatible workaround that takes very little time. No such useless feature can justify the bugs.
May 10 2016
parent reply Brian Schott <briancschott gmail.com> writes:
On Tuesday, 10 May 2016 at 10:00:04 UTC, Guillaume Piolat wrote:
 KILL IT NOW, WITH FIRE
Then salt the ground it grew on and irradiate it. The comma operator has stolen our ability to have tuples and in return it has given us bugs.
May 10 2016
parent Seb <seb wilzba.ch> writes:
On Tuesday, 10 May 2016 at 10:02:53 UTC, Brian Schott wrote:
 On Tuesday, 10 May 2016 at 10:00:04 UTC, Guillaume Piolat wrote:
 KILL IT NOW, WITH FIRE
Then salt the ground it grew on and irradiate it. The comma operator has stolen our ability to have tuples and in return it has given us bugs.
... and then send the ashes to space! Free the tuples!
May 10 2016
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/10/16 12:52 PM, Mathias Lang wrote:
 So, following DConf2016, I raised a P.R. to deprecate usage of the comma
 expressions, except within `for` loops increment [5].
The agreed-upon ideea was to allow uses that don't use the result (including for loops). No? -- Andrei
May 10 2016
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/10/16 1:09 PM, Andrei Alexandrescu wrote:
 On 5/10/16 12:52 PM, Mathias Lang wrote:
 So, following DConf2016, I raised a P.R. to deprecate usage of the comma
 expressions, except within `for` loops increment [5].
The agreed-upon ideea was to allow uses that don't use the result (including for loops). No? -- Andrei
In fact I thought that got implemented a while ago, that's why I didn't insist much lately. -- Andrei
May 10 2016
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 5/10/16 6:13 AM, Andrei Alexandrescu wrote:
 On 5/10/16 1:09 PM, Andrei Alexandrescu wrote:
 On 5/10/16 12:52 PM, Mathias Lang wrote:
 So, following DConf2016, I raised a P.R. to deprecate usage of the comma
 expressions, except within `for` loops increment [5].
The agreed-upon ideea was to allow uses that don't use the result (including for loops). No? -- Andrei
In fact I thought that got implemented a while ago, that's why I didn't insist much lately. -- Andrei
It was never pulled. In fact, Marc Schütz just closed his PR when he found Mathias' PR. https://github.com/dlang/dmd/pull/5737#issuecomment-217946868 Note, there was some pretty good examples of (ab)use of the comma operator in one of those: https://github.com/dlang/dmd/pull/3399#issuecomment-38401339 For my input, I say kill it with fire, but only after deprecation :) When you see the kinds of bugs this has caused, it's horrifying. I agree with your proposed solution (and so does Daniel Murphy BTW). Sadly, I don't know if true tuple support can be had anytime soon, we may need to wait a long time for that. BTW, has anyone proposed a replacement like this? auto ref comma(T...)(auto ref T t) if(T.length > 1) { return t[$-1]; } Sure seems doable without a language feature. Just replace x, y with comma(x, y). On 5/10/16 5:52 AM, Mathias Lang wrote:
 As documented in TDPL (thanks  schveiguy) [2].
I can't take credit for this, Ali pointed it out to me after his talk when I pointed out the problem during the talk. He said something along the lines of "I knew I had not made this up and had seen it somewhere!" -Steve
May 10 2016
next sibling parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Tue, May 10, 2016 at 08:49:28AM -0400, Steven Schveighoffer via
Digitalmars-d wrote:
[...]
 For my input, I say kill it with fire, but only after deprecation :)
 When you see the kinds of bugs this has caused, it's horrifying.
+1. Kill the comma operator with fire. Usage in for-loops should be done as special-case syntax, *not* as comma operator (i.e., "," in for loops should be accepted as part of for-loop statement syntax, not as part of expression syntax). What to do with tuple syntax is a different kettle o' fish. But before we get there, we need to kill comma first. So let's at least take this first step. --T
May 10 2016
prev sibling next sibling parent reply Kagamin <spam here.lot> writes:
On Tuesday, 10 May 2016 at 12:49:28 UTC, Steven Schveighoffer 
wrote:
 Note, there was some pretty good examples of (ab)use of the 
 comma operator in one of those: 
 https://github.com/dlang/dmd/pull/3399#issuecomment-38401339
If we had control flow statements as expressions one could rewrite return a(), b; as a(), return b; and thus wouldn't need the C comma expression semantics.
May 11 2016
parent ZombineDev <petar.p.kirov gmail.com> writes:
On Wednesday, 11 May 2016 at 09:03:29 UTC, Kagamin wrote:
 On Tuesday, 10 May 2016 at 12:49:28 UTC, Steven Schveighoffer 
 wrote:
 Note, there was some pretty good examples of (ab)use of the 
 comma operator in one of those: 
 https://github.com/dlang/dmd/pull/3399#issuecomment-38401339
If we had control flow statements as expressions one could rewrite return a(), b; as a(), return b; and thus wouldn't need the C comma expression semantics.
I haven't found any use for control flow statements as expressions in D (even though I have programmed in Ruby) so far, because the ternary operator covers all my needs. In this case the intent would be much more clear if you wrote: a(); return b;
May 11 2016
prev sibling parent Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Tuesday, 10 May 2016 at 12:49:28 UTC, Steven Schveighoffer 
wrote:
 BTW, has anyone proposed a replacement like this?

 auto ref comma(T...)(auto ref T t) if(T.length > 1)
 {
    return t[$-1];
 }
That won't work with void expressions. Here's a version which does: https://github.com/CyberShadow/ae/commit/1405e9deff60d33952e52600bc1d1fcbf3511084
May 17 2017
prev sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Tuesday, 10 May 2016 at 10:09:40 UTC, Andrei Alexandrescu 
wrote:
 On 5/10/16 12:52 PM, Mathias Lang wrote:
 So, following DConf2016, I raised a P.R. to deprecate usage of 
 the comma
 expressions, except within `for` loops increment [5].
The agreed-upon ideea was to allow uses that don't use the result (including for loops). No? -- Andrei
Let's just make it of void type, there was plan to recycle the syntax maybe, but whatever we do in the future, this is the sensible first step.
May 10 2016
parent reply Lionello Lunesu <lionello lunesu.remove.com> writes:
On 10/5/2016 22:16, deadalnix wrote:
 On Tuesday, 10 May 2016 at 10:09:40 UTC, Andrei Alexandrescu wrote:
 On 5/10/16 12:52 PM, Mathias Lang wrote:
 So, following DConf2016, I raised a P.R. to deprecate usage of the comma
 expressions, except within `for` loops increment [5].
The agreed-upon ideea was to allow uses that don't use the result (including for loops). No? -- Andrei
Let's just make it of void type, there was plan to recycle the syntax maybe, but whatever we do in the future, this is the sensible first step.
Acutally, we can do two-birds-one-stone: instead of making it void, make it a value tuple! If the result of the comma operator gets used in a bug prone matter it would cause a compile error! How is that for "Yeah, sorry, we broke your code, but look what you got in return!" Win-win!
May 11 2016
parent reply deadalnix <deadalnix gmail.com> writes:
On Wednesday, 11 May 2016 at 10:50:47 UTC, Lionello Lunesu wrote:
 On 10/5/2016 22:16, deadalnix wrote:
 On Tuesday, 10 May 2016 at 10:09:40 UTC, Andrei Alexandrescu 
 wrote:
 On 5/10/16 12:52 PM, Mathias Lang wrote:
 So, following DConf2016, I raised a P.R. to deprecate usage 
 of the comma
 expressions, except within `for` loops increment [5].
The agreed-upon ideea was to allow uses that don't use the result (including for loops). No? -- Andrei
Let's just make it of void type, there was plan to recycle the syntax maybe, but whatever we do in the future, this is the sensible first step.
Acutally, we can do two-birds-one-stone: instead of making it void, make it a value tuple!
No. You can't change semantic to something that'll still work under the feet of the user. If this syntax is to be recycled to tuple, the value needs to be void for a while as to shake out uses. It is safe to go from void to something else, it isn't not to go from something to something else.
May 11 2016
parent reply Lionello Lunesu <lionello lunesu.remove.com> writes:
On 11/5/2016 21:13, deadalnix wrote:
 On Wednesday, 11 May 2016 at 10:50:47 UTC, Lionello Lunesu wrote:
 On 10/5/2016 22:16, deadalnix wrote:
 On Tuesday, 10 May 2016 at 10:09:40 UTC, Andrei Alexandrescu wrote:
 On 5/10/16 12:52 PM, Mathias Lang wrote:
 So, following DConf2016, I raised a P.R. to deprecate usage of the
 comma
 expressions, except within `for` loops increment [5].
The agreed-upon ideea was to allow uses that don't use the result (including for loops). No? -- Andrei
Let's just make it of void type, there was plan to recycle the syntax maybe, but whatever we do in the future, this is the sensible first step.
Acutally, we can do two-birds-one-stone: instead of making it void, make it a value tuple!
No. You can't change semantic to something that'll still work under the feet of the user. If this syntax is to be recycled to tuple, the value needs to be void for a while as to shake out uses. It is safe to go from void to something else, it isn't not to go from something to something else.
I agree with you when the 1st something and 2nd something are somehow compatible. void is also a something, but it'd work because it'd never silently change the meaning of code. I'm trying to think of a case where changing a single value into a tuple with 2 (or more) values would silently change the behavior, but I can't think of any. Seems to me it would always cause an error, iff the result of the comma operator gets used.
May 11 2016
parent reply Nick Treleaven <ntrel-pub mybtinternet.com> writes:
On Thursday, 12 May 2016 at 02:51:33 UTC, Lionello Lunesu wrote:
 I'm trying to think of a case where changing a single value 
 into a tuple with 2 (or more) values would silently change the 
 behavior, but I can't think of any. Seems to me it would always 
 cause an error, iff the result of the comma operator gets used.
int x,y; auto f() {return (x=4,y);} ... auto z = f(); static if (!is(typeof(z) == int) voteForTrump(); ;-) In practice, this is more plausible with function overloading - i.e. z.overload() calling a different function. If the comma operator returns void, the `auto z` line and f().overload() both fail.
May 13 2016
parent Lionello Lunesu <lionello lunesu.remove.com> writes:
On 13/5/2016 20:44, Nick Treleaven wrote:
 On Thursday, 12 May 2016 at 02:51:33 UTC, Lionello Lunesu wrote:
 I'm trying to think of a case where changing a single value into a
 tuple with 2 (or more) values would silently change the behavior, but
 I can't think of any. Seems to me it would always cause an error, iff
 the result of the comma operator gets used.
int x,y; auto f() {return (x=4,y);} ... auto z = f(); static if (!is(typeof(z) == int) voteForTrump(); ;-) In practice, this is more plausible with function overloading - i.e. z.overload() calling a different function. If the comma operator returns void, the `auto z` line and f().overload() both fail.
Good point. Thanks.
May 20 2016
prev sibling next sibling parent Martin Krejcirik <mk-junk i-line.cz> writes:
I'd prefer just adding a warning where appropriate.
May 10 2016
prev sibling next sibling parent reply ixid <adamsibson hotmail.com> writes:
On Tuesday, 10 May 2016 at 09:52:07 UTC, Mathias Lang wrote:
 Do you like comma expressions, and think its presence in the 
 language is more pro than con ?
Kill it with fire and hopefully we can have pretty tuple syntax like Swift and Go's.
May 10 2016
parent Tomer Filiba <tomerfiliba gmail.com> writes:
On Tuesday, 10 May 2016 at 12:27:42 UTC, ixid wrote:
 Kill it with fire and hopefully we can have pretty tuple syntax 
 like Swift and Go's.
Yes please!
May 10 2016
prev sibling next sibling parent reply Meta <jared771 gmail.com> writes:
 Do you like comma expressions, and think its presence in the 
 language is more pro than con ?
It should've been killed off a long time ago. It only causes bugs and can easily be replaced with a library feature if necessary. I think Andrei suggested that it should be changed so that the comma expression returns `void` instead of the last expression evaluated.
May 10 2016
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 10.05.2016 15:53, Meta wrote:
 Do you like comma expressions, and think its presence in the language
 is more pro than con ?
It should've been killed off a long time ago. It only causes bugs and can easily be replaced with a library feature if necessary. I think Andrei suggested that it should be changed so that the comma expression returns `void` instead of the last expression evaluated.
That's not really forward compatible to tuple support, e.g., one can query typeof((1,2)).
May 10 2016
parent Meta <jared771 gmail.com> writes:
On Tuesday, 10 May 2016 at 14:07:35 UTC, Timon Gehr wrote:
 That's not really forward compatible to tuple support, e.g., 
 one can query typeof((1,2)).
I am becoming increasingly dubious that D will ever have built-in tuples.
May 10 2016
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 5/10/16 9:53 AM, Meta wrote:
 Do you like comma expressions, and think its presence in the language
 is more pro than con ?
It should've been killed off a long time ago. It only causes bugs and can easily be replaced with a library feature if necessary. I think Andrei suggested that it should be changed so that the comma expression returns `void` instead of the last expression evaluated.
Andrei pointed out (in an earlier PR) that making the return type void isn't correct either. You can still use void in some cases, e.g.: auto foo(a) { return ++a, ++a; } This should still be disallowed. -Steve
May 10 2016
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 10.05.2016 19:57, Steven Schveighoffer wrote:
 On 5/10/16 9:53 AM, Meta wrote:
 Do you like comma expressions, and think its presence in the language
 is more pro than con ?
It should've been killed off a long time ago. It only causes bugs and can easily be replaced with a library feature if necessary. I think Andrei suggested that it should be changed so that the comma expression returns `void` instead of the last expression evaluated.
Andrei pointed out (in an earlier PR) that making the return type void isn't correct either. You can still use void in some cases, e.g.: auto foo(a) { return ++a, ++a; } This should still be disallowed. -Steve
I suggest we make it a statement instead of an expression and add special syntax for for-loops.
May 10 2016
prev sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Tuesday, 10 May 2016 at 17:57:38 UTC, Steven Schveighoffer 
wrote:
 On 5/10/16 9:53 AM, Meta wrote:
 Do you like comma expressions, and think its presence in the 
 language
 is more pro than con ?
It should've been killed off a long time ago. It only causes bugs and can easily be replaced with a library feature if necessary. I think Andrei suggested that it should be changed so that the comma expression returns `void` instead of the last expression evaluated.
Andrei pointed out (in an earlier PR) that making the return type void isn't correct either. You can still use void in some cases, e.g.: auto foo(a) { return ++a, ++a; } This should still be disallowed. -Steve
It doesn't make it incorrect, just insufficient.
May 10 2016
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 10.05.2016 23:47, deadalnix wrote:
 On Tuesday, 10 May 2016 at 17:57:38 UTC, Steven Schveighoffer wrote:
 On 5/10/16 9:53 AM, Meta wrote:
 Do you like comma expressions, and think its presence in the language
 is more pro than con ?
It should've been killed off a long time ago. It only causes bugs and can easily be replaced with a library feature if necessary. I think Andrei suggested that it should be changed so that the comma expression returns `void` instead of the last expression evaluated.
Andrei pointed out (in an earlier PR) that making the return type void isn't correct either. You can still use void in some cases, e.g.: auto foo(a) { return ++a, ++a; } This should still be disallowed. -Steve
It doesn't make it incorrect, just insufficient.
Let's make it correct and sufficient.
May 10 2016
prev sibling next sibling parent reply Observer <here nowhere.org> writes:
On Tuesday, 10 May 2016 at 09:52:07 UTC, Mathias Lang wrote:
 So, following DConf2016, I raised a P.R. to deprecate usage of 
 the comma expressions, except within `for` loops increment [5].
 ...
 It seems there is a reasonable ground to kill it. However, 
 there have been legitimated concern about code breakage, so we 
 would like to hear from other people:

 Do you like comma expressions, and think its presence in the 
 language is more pro than con ?
I've programmed in C for decades, and in Perl for a decade, and *never* had a problem with the comma operator in either language. While I haven't been part of any D-language discussions about this operator, I fail to see it as causing serious code problems. Perl in particular uses commas extensively, both as a C-type operator and in list construction. Perl is helped in that regard by distinguishing scalar context (C-type operator) from list context (list argument separator). The fact of the matter is, anyone who learns Perl finds this spectacularly unconfusing. So perhaps a better solution than throwing away the operator in D is to think about supporting proper context-awareness. It's been done before (as demonstrated in Perl) with great success, so we definitely can't say it's an impossibility. And D already understands one ubiquitous list-construction context, namely the act of passing arguments to functions. Now admittedly, there aren't too many situations where the comma acting as a C-type operator finds a use. But commas in all of the for-loop control expressions, not just the increment clause, are definitely useful. And more than that, they're useful whenever you want to execute several independent calculations in some context that doesn't allow "statement expressions". See http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html for how this is supported in GNU C, with a very clean syntax. I would strongly suggest that if you want to deprecate the comma operator for some reason, that you build statement expressions into the language, allow them in all contexts where comma operators are presently very common, and document this widely as a standard idiom in the language. Note that for-loops are definitely not the only places where comma operators come in handy. As an example, I wrote a very long critique of TDPL, and sent it off to Andrei late last year. In an item for page 382, I provided a lot of replacement text to clarify the example. Within that text was the following delegate code, showing excellent use of the comma operator in a do-while loop-control context: (i) { bool __done = false; do { writeln(i); } while (__done = true, !__done); // __done is still false if and only if the loop body executed // a break and skipped the reassignment within the while test. return __done ? 0 : 1; } That's actually rather tricky code. In the general case for such a loop, you cannot simply move the "__done = true" assignment and place it at the end of the loop body, to avoid use of the comma operator. That's because the code earlier in the loop body might contain a "continue" statement, and that would skip right by the assignment if it were part of the loop body instead of being part of the loop-condition expression. So whatever is done with the comma operator in D, you first need to enumerate all the places where it is truly useful, and make sure you support those cases well. I find the present syntax very simple and very readable, and so would be very reluctant to give it up. If there is really a need to do so, then allowing brace-enclosed statement expressions seems to me to be a reasonable compromise, requiring only clean, very little extra syntax. If you do make this kind of transition, it needs to be spread across multiple compiler releases. In particular, you should never proceed to the next stage until *all* the major compilers (DMD, GCC, LDC) have caught up to the present stage. * Release 1: Implement statement expressions, allow them in all the right contexts, and document them. Using this release, acquire real-world experience and fix any implementation bugs. * Release 2: Now that statement expressions are known to be well-supported, document them as being idiomatic in common contexts such as loop control, recommend their use, and document that the comma operator will be deprecated in future releases. Provide a compiler option (documented but defaulted off at this stage) to warn about use of the comma operator in places where a statement expression would do the trick instead, to allow developers to quickly locate places that deserve some attention. Make no other changes to the compilers at this stage, because it is only now that statement expressions will be known to be safe enough for general use, and you want to allow a period for pleasant, well-planned conversions before the hammer comes down. Also in this timeframe, see if dfix can be equipped to handle such conversions automatically. * Release 3: Still allow the comma operator, but now default the comma-operator deprecation warning to be on. And declare in the documentation that this is the case, and that this will be the last release in which the comma operator is still allowed. * Release 4: Obsolete the comma operator entirely. Have the compiler generate an error, aborting the compilation, instead of a warning, if comma operators are found during compilation. * Release 5: Finally allow the language definition to re-use the comma for other purposes (tuple construction, or whatever). A slow evolution like that is the only sane way to proceed. But again, that's only if context-awareness is not possible, and I find that hard to believe.
May 10 2016
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 10.05.2016 23:30, Observer wrote:
 I've programmed in C for decades, and in Perl for a decade, and *never*
 had a problem with the comma operator in either language.
Neither have I. It's a cheap claim to make though, and it does not really add anything relevant to the discussion.
 While I
 haven't been part of any D-language discussions about this operator,
 I fail to see it as causing serious code problems.
 ...
Lack of proper tuples is a serious enough problem.
 Now admittedly, there aren't too many situations where the comma acting
 as a C-type operator finds a use.  But commas in all of the for-loop
 control expressions, not just the increment clause, are definitely useful.
 And more than that, they're useful whenever you want to execute several
 independent calculations in some context that doesn't allow "statement
 expressions".  See http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
 for how this is supported in GNU C, with a very clean syntax.  I would
 strongly suggest that if you want to deprecate the comma operator for
 some reason, that you build statement expressions into the language,
The comma operator does not allow executing statements, but delegates can do this even today. auto var = { stmt1; stmt2; stmt3; return expr; }(); Also, tuples can do everything that comma expressions can.
 allow them in all contexts where comma operators are presently very
 common, and document this widely as a standard idiom in the language.

 Note that for-loops are definitely not the only places where comma
 operators come in handy.  As an example, I wrote a very long critique
 of TDPL, and sent it off to Andrei late last year.  In an item for
 page 382, I provided a lot of replacement text to clarify the example.
 Within that text was the following delegate code, showing excellent use
 of the comma operator in a do-while loop-control context:

 (i) {
      bool __done = false;
      do {
          writeln(i);
      } while (__done = true, !__done);
      // __done is still false if and only if the loop body executed
      // a break and skipped the reassignment within the while test.
      return __done ? 0 : 1;
 }
That loop body does not contain any breaks. It would be nice if the presented use case actually made sense. Also, just write while(_done=true,false);
 That's actually rather tricky code.  In the general case for such a loop,
 you cannot simply move the "__done = true" assignment and place it at the
 end of the loop body,
Which a careless maintainer of the code might still do, and now you have a bug. Whatever your actual use case was, I think it is likely that there is a more elegant solution that does not require a comment (about control flow!) to prevent such accidents from happening.
May 10 2016
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 10.05.2016 23:52, Timon Gehr wrote:
 Also, tuples can do everything that comma expressions can.
Actually, that doesn't work for 'void' (because 'void' is a type that is not actually a type) in every conceivable design. Should probably just be made to work.
May 10 2016
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 10.05.2016 11:52, Mathias Lang wrote:
 It seems there is a reasonable ground to kill it. However, there have
 been legitimated concern about code breakage, so we would like to hear
 from other people:

 Do you like comma expressions,
It's sometimes a useful thing to do. But every usage of the comma operator, e.g. (e1,e2,e3), could just be e.g. (e1,e2,e3)[$-1] instead with tuple syntax, and the latter is a lot more explicit. The two usages that don't conflict with tuple syntax (i.e. as a statement/inside a for-loop) could just be left in. They tend not to hurt.
 and think its presence in the language is
 more pro than con ?
No. Kill it.
May 10 2016
next sibling parent reply Stefan Koch <uplink.coder googlemail.com> writes:
On Tuesday, 10 May 2016 at 21:30:35 UTC, Timon Gehr wrote:
 Kill it.
I agree. There is always another way.
May 10 2016
next sibling parent reply =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
On Tuesday, 10 May 2016 at 21:33:47 UTC, Stefan Koch wrote:
 On Tuesday, 10 May 2016 at 21:30:35 UTC, Timon Gehr wrote:
 Kill it.
I agree.
Agreed. Builtin tuple syntax is far more useful.
May 10 2016
parent reply mogu <mogucpp 163.com> writes:
On Tuesday, 10 May 2016 at 21:49:10 UTC, Nordlöw wrote:
 On Tuesday, 10 May 2016 at 21:33:47 UTC, Stefan Koch wrote:
 On Tuesday, 10 May 2016 at 21:30:35 UTC, Timon Gehr wrote:
 Kill it.
I agree.
Agreed. Builtin tuple syntax is far more useful.
+1. And personally, match is expected then.
May 10 2016
parent reply Mithun Hunsur <me philpax.me> writes:
On Tuesday, 10 May 2016 at 23:33:13 UTC, mogu wrote:
 On Tuesday, 10 May 2016 at 21:49:10 UTC, Nordlöw wrote:
 On Tuesday, 10 May 2016 at 21:33:47 UTC, Stefan Koch wrote:
 On Tuesday, 10 May 2016 at 21:30:35 UTC, Timon Gehr wrote:
 Kill it.
I agree.
Agreed. Builtin tuple syntax is far more useful.
+1. And personally, match is expected then.
+1. The comma operator should go, especially if it makes tuple syntax possible.
May 10 2016
parent reply Kagamin <spam here.lot> writes:
On Wednesday, 11 May 2016 at 00:32:33 UTC, Mithun Hunsur wrote:
 +1. The comma operator should go, especially if it makes tuple 
 syntax possible.
To clarify a possible misunderstanding: tuples are possible in D3, and macros, and concepts, and parametric polymorphism.
May 11 2016
parent reply ZombineDev <petar.p.kirov gmail.com> writes:
On Wednesday, 11 May 2016 at 09:06:40 UTC, Kagamin wrote:
 On Wednesday, 11 May 2016 at 00:32:33 UTC, Mithun Hunsur wrote:
 +1. The comma operator should go, especially if it makes tuple 
 syntax possible.
To clarify a possible misunderstanding: tuples are possible in D3, and macros, and concepts, and parametric polymorphism.
By "parametric polymorphism" do you mean multiple dispatch/multimethods? This can sort of be emulated in library. Think something like Variant.visit that takes multiple variants as parameters. So building it into the language doesn't seem like it should be a priority. Concepts are the wrong solution to the problem and probably would never happen. The design of std.experimental.allocator proves that they are inadequate for solving even simple problems like static polymorphism. Macros... well I think a solution like Jonathan Blow's Jai CTFE inside the compiler would be much more powerful and easy to integrate into the language. But it will require heavy refactoring of DMDFE, but this is a good idea regardless. Tuples and some sort of pattern matching for values (like is() is for types) are a total must have. Though if we get rid of the comma operator, it may happen earlier than D3. From watching D's evolution from last 2-3 years I think that there may never be a D3. Just cool new features that every other release, and graceful deprecation of old misfeatures.
May 11 2016
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 11.05.2016 11:39, ZombineDev wrote:
 By "parametric polymorphism" do you mean multiple dispatch/multimethods?
It's a type system feature. It allows one uniform implementation to work on different types without a loss of type information (i.e., by using a variant, or up-casting to a less specific type). Templates are often used to solve similar problems, but they give you different implementations if you ask for different types, which does not work for delegates and function pointers (including virtual functions), if you need to recurse with changing type arguments, etc. 'inout' is a very restricted form of this. I don't think this is on the same level as tuple support though.
May 11 2016
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2016-05-11 11:39, ZombineDev wrote:

 Macros... well I think a solution like Jonathan Blow's Jai CTFE inside
 the compiler would be much more powerful and easy to integrate into the
 language. But it will require heavy refactoring of DMDFE, but this is a
 good idea regardless.
Macros are not hard to implement, at least not the kinds that Scala is using.
 Tuples and some sort of pattern matching for values (like is() is for
 types) are a total must have. Though if we get rid of the comma
 operator, it may happen earlier than D3. From watching D's evolution
 from last 2-3 years I think that there may never be a D3. Just cool new
 features that every other release, and graceful deprecation of old
 misfeatures.
Pattern matching can be implemented as a library. That syntax will not be very nice though. But perhaps with macros ;) -- /Jacob Carlborg
May 11 2016
prev sibling parent Andy Smith <andyrsmith googlemail.com> writes:
On Tuesday, 10 May 2016 at 21:33:47 UTC, Stefan Koch wrote:
 On Tuesday, 10 May 2016 at 21:30:35 UTC, Timon Gehr wrote:
 Kill it.
I agree. There is always another way.
+1 for killing. If there's a language feature that allows someone of Ali's calibre to write some code expecting one behaviour whilst under the hood receiving a completely different behaviour then I think that's a clear case for removing and/or ring-fencing said feature, since it clearly violates the principle of least surprise. If it can trip up Ali then we mere mortals are clearly doomed!!!! :-) Cheers, A.
May 10 2016
prev sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Tuesday, 10 May 2016 at 21:30:35 UTC, Timon Gehr wrote:
 and think its presence in the language is
 more pro than con ?
No. Kill it.
With FIRE !
May 10 2016
parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Tue, May 10, 2016 at 09:46:36PM +0000, deadalnix via Digitalmars-d wrote:
 On Tuesday, 10 May 2016 at 21:30:35 UTC, Timon Gehr wrote:
and think its presence in the language is more pro than con ?
No. Kill it.
With FIRE !
And extreme prejudice. T -- That's not a bug; that's a feature!
May 10 2016
prev sibling next sibling parent NotSpooky <NotMyActual email.com> writes:
I think we should kill it. Already had a nasty bug with it.
May 10 2016
prev sibling next sibling parent reply Gopan <gggopan gmail.com> writes:
On Tuesday, 10 May 2016 at 09:52:07 UTC, Mathias Lang wrote:

 Do you like comma expressions, ...
I am a student. In C, one scenario where I like comma is this. int x; while( scanf("%d", &x), x!= 0) // until user input 0. { //do something with x } Without the comma operator, I would have to repeat the scanf statement. int x; scanf("%d", &x); while(x != 0) { //do something with x scanf("%d", &x); } Does anybody think that this is a useful case of comma operator?
May 11 2016
next sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On Wednesday, 11 May 2016 at 13:29:56 UTC, Gopan wrote:
 On Tuesday, 10 May 2016 at 09:52:07 UTC, Mathias Lang wrote:

 Do you like comma expressions, ...
I am a student. In C, one scenario where I like comma is this. int x; while( scanf("%d", &x), x!= 0) // until user input 0. { //do something with x } Without the comma operator, I would have to repeat the scanf statement. int x; scanf("%d", &x); while(x != 0) { //do something with x scanf("%d", &x); } Does anybody think that this is a useful case of comma operator?
What if scanf fails or hits eof? A better call: while(scanf("%d", &x) > 0 && x != 0) -Steve
May 11 2016
prev sibling next sibling parent reply burjui <bytefu gmail.com> writes:
On Wednesday, 11 May 2016 at 13:29:56 UTC, Gopan wrote:
 int x;
 while( scanf("%d", &x),  x!= 0) // until user input 0.
 {
    //do something with x
 }

 Does anybody think that this is a useful case of comma operator?
Well, it is, but judging from my experience, comma operator is the most rarely used part of the language. I hardly ever needed it in C and C++, where it originated, same with D and Java. In fact, I had to check if it works in Java at all - turned out, it's only allowed in "for" loops. Just never used it and forgot about it. The comma operator does more harm than good, is very rarely used and is far less usable than tuples, so I'm all for killing it (except in "for" loops).
May 11 2016
parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Wed, May 11, 2016 at 02:37:37PM +0000, burjui via Digitalmars-d wrote:
 On Wednesday, 11 May 2016 at 13:29:56 UTC, Gopan wrote:
int x;
while( scanf("%d", &x),  x!= 0) // until user input 0.
{
   //do something with x
}

Does anybody think that this is a useful case of comma operator?
Well, it is, but judging from my experience, comma operator is the most rarely used part of the language. I hardly ever needed it in C and C++, where it originated, same with D and Java. In fact, I had to check if it works in Java at all - turned out, it's only allowed in "for" loops. Just never used it and forgot about it. The comma operator does more harm than good, is very rarely used and is far less usable than tuples, so I'm all for killing it (except in "for" loops).
That's what I've been saying, it should be treated as a special case in the syntax of for-loops, but not as an operator in general. T -- A computer doesn't mind if its programs are put to purposes that don't match their names. -- D. Knuth
May 11 2016
parent reply deadalnix <deadalnix gmail.com> writes:
On Wednesday, 11 May 2016 at 16:44:43 UTC, H. S. Teoh wrote:
 That's what I've been saying, it should be treated as a special 
 case in the syntax of for-loops, but not as an operator in 
 general.
Please no special cases.
May 11 2016
parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Wed, May 11, 2016 at 05:55:27PM +0000, deadalnix via Digitalmars-d wrote:
 On Wednesday, 11 May 2016 at 16:44:43 UTC, H. S. Teoh wrote:
That's what I've been saying, it should be treated as a special case
in the syntax of for-loops, but not as an operator in general.
Please no special cases.
You misunderstand, what I mean is that the comma should be *part of* for-loop syntax, instead of being part of expression syntax. I.e., for-loop grammar should read something like this: for-loop: "for" "(" loop-init ";" loop-condition ";" loop-increment ")" block loop-init: comma-separated-exprs loop-condition: comma-separated-exprs loop-increment: comma-separated-exprs comma-separated-exprs: expression expression "," comma-separated-exprs And the grammar for expression should have zero references to comma operators. T -- The right half of the brain controls the left half of the body. This means that only left-handed people are in their right mind. -- Manoj Srivastava
May 11 2016
parent reply deadalnix <deadalnix gmail.com> writes:
On Wednesday, 11 May 2016 at 18:36:11 UTC, H. S. Teoh wrote:
 On Wed, May 11, 2016 at 05:55:27PM +0000, deadalnix via 
 Digitalmars-d wrote:
 On Wednesday, 11 May 2016 at 16:44:43 UTC, H. S. Teoh wrote:
That's what I've been saying, it should be treated as a 
special case in the syntax of for-loops, but not as an 
operator in general.
Please no special cases.
You misunderstand, what I mean is that the comma should be *part of* for-loop syntax, instead of being part of expression syntax. I.e., for-loop grammar should read something like this: for-loop: "for" "(" loop-init ";" loop-condition ";" loop-increment ")" block loop-init: comma-separated-exprs loop-condition: comma-separated-exprs loop-increment: comma-separated-exprs comma-separated-exprs: expression expression "," comma-separated-exprs And the grammar for expression should have zero references to comma operators. T
loopinit is a statement, but I see the idea. Works for me.
May 11 2016
parent Mathias Lang via Digitalmars-d <digitalmars-d puremagic.com> writes:
2016-05-12 0:32 GMT+02:00 deadalnix via Digitalmars-d <
digitalmars-d puremagic.com>:

 On Wednesday, 11 May 2016 at 18:36:11 UTC, H. S. Teoh wrote:

 On Wed, May 11, 2016 at 05:55:27PM +0000, deadalnix via Digitalmars-d
 wrote:

 On Wednesday, 11 May 2016 at 16:44:43 UTC, H. S. Teoh wrote:
That's what I've been saying, it should be treated as a >special case
in the syntax of for-loops, but not as an >operator in general.

 Please no special cases.
You misunderstand, what I mean is that the comma should be *part of* for-loop syntax, instead of being part of expression syntax. I.e., for-loop grammar should read something like this: for-loop: "for" "(" loop-init ";" loop-condition ";" loop-increment ")" block loop-init: comma-separated-exprs loop-condition: comma-separated-exprs loop-increment: comma-separated-exprs comma-separated-exprs: expression expression "," comma-separated-exprs And the grammar for expression should have zero references to comma operators. T
loopinit is a statement, but I see the idea. Works for me.
That is my intent too. However the discussions on the P.R. seem to converge in another direction.
May 11 2016
prev sibling next sibling parent reply Nick Treleaven <ntrel-pub mybtinternet.com> writes:
On Wednesday, 11 May 2016 at 13:29:56 UTC, Gopan wrote:
 int x;
 while( scanf("%d", &x),  x!= 0) // until user input 0.
 {
    //do something with x
 }

 Without the comma operator, I would have to repeat the scanf 
 statement.
 int x;
 scanf("%d", &x);
 while(x != 0)
 {
    //do something with x
    scanf("%d", &x);
 }
Aside from scanf specifics, you shouldn't repeat the setup code, use do...while(true) with if and break. In places where the comma operator does help, use a comma(expr,result) template function, implemented here: http://forum.dlang.org/post/ngslcl$otg$1 digitalmars.com
May 11 2016
next sibling parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Wed, May 11, 2016 at 04:46:48PM +0000, Nick Treleaven via Digitalmars-d
wrote:
 On Wednesday, 11 May 2016 at 13:29:56 UTC, Gopan wrote:
int x;
while( scanf("%d", &x),  x!= 0) // until user input 0.
{
   //do something with x
}

Without the comma operator, I would have to repeat the scanf
statement.
int x;
scanf("%d", &x);
while(x != 0)
{
   //do something with x
   scanf("%d", &x);
}
Aside from scanf specifics, you shouldn't repeat the setup code, use do...while(true) with if and break.
[...] Actually, the 2nd way he wrote it above is my preferred way, because it reveals the correspondence between the structure of the code and the structure of the data better than any of the various shortcuts people like to write. But a far superior way is to encapsulate reading input as a range (or equivalent data source) and completely separate the data source from the data processing: auto scanInts() { struct Range { bool empty = true; int front; void popFront() { if (scanf("%d", &front) > 0) empty = false; } } Range r; r.popFront(); return r; } foreach (x; ScanfRange().until!(x => x != 0)) { // do something with x } This way your data processing code doesn't ever have to worry about the dirty details of how to loop over scanf calls, and can easily be hooked into a different data source with minimal changes. T -- I am Ohm of Borg. Resistance is voltage over current.
May 11 2016
parent Gopan <gggopan gmail.com> writes:
On Wednesday, 11 May 2016 at 17:00:41 UTC, H. S. Teoh wrote:
 On Wed, May 11, 2016 at 04:46:48PM +0000, Nick Treleaven via 
 Digitalmars-d wrote:
 On Wednesday, 11 May 2016 at 13:29:56 UTC, Gopan wrote:
int x;
while( scanf("%d", &x),  x!= 0) // until user input 0.
{
   //do something with x
}

Without the comma operator, I would have to repeat the scanf
statement.
int x;
scanf("%d", &x);
while(x != 0)
{
   //do something with x
   scanf("%d", &x);
}
Aside from scanf specifics, you shouldn't repeat the setup code, use do...while(true) with if and break.
[...] Actually, the 2nd way he wrote it above is my preferred way, because it reveals the correspondence between the structure of the code and the structure of the data better than any of the various shortcuts people like to write.
The problem with the second way is that the piece of code (scanf) that prepares the condition (x!=0) appears two times. One before the while-loop and one towards the end of the while-loop block. In a maintenance project, this duplication is a problem. Somebody doing a bug fix is probable to do the fix in only one place, missing the other. That was what I tried to avoid by using comma. When there are multiple setup stattement, I too prefer the other trick (Nick Treleaven's comment) do { [ code that sets up condition-expression] if(expression) break; }while(true);
 But a far superior way is to encapsulate reading input as a 
 range (or equivalent data source) and completely separate the 
 data source from the data processing:

 	auto scanInts() {
 		struct Range {
 			bool empty = true;
 			int front;
 			void popFront() {
 				if (scanf("%d", &front) > 0)
 					empty = false;
 			}
 		}
 		Range r;
 		r.popFront();
 		return r;
 	}

 	foreach (x; ScanfRange().until!(x => x != 0)) {
 		// do something with x
 	}

 This way your data processing code doesn't ever have to worry 
 about the dirty details of how to loop over scanf calls, and 
 can easily be hooked into a different data source with minimal 
 changes.


 T
May 11 2016
prev sibling next sibling parent reply Kagamin <spam here.lot> writes:
On Wednesday, 11 May 2016 at 16:46:48 UTC, Nick Treleaven wrote:
 In places where the comma operator does help,  use a 
 comma(expr,result) template function, implemented here:
 http://forum.dlang.org/post/ngslcl$otg$1 digitalmars.com
May not always work: https://dpaste.dzfl.pl/1ea0df70787b
May 11 2016
next sibling parent reply Kagamin <spam here.lot> writes:
Eeek, dpaste swallowed error message :)
May 11 2016
parent reply Kagamin <spam here.lot> writes:
https://dpaste.dzfl.pl/46f24c3def62
May 11 2016
parent reply Gopan <gggopan gmail.com> writes:
On Wednesday, 11 May 2016 at 17:15:29 UTC, Kagamin wrote:
 https://dpaste.dzfl.pl/46f24c3def62
It gave compilation error because, one of the parameters of the comma() template in your code is void. Currently, does D support void as a type of an expression separated by comma?
May 11 2016
parent Kagamin <spam here.lot> writes:
On Wednesday, 11 May 2016 at 18:37:15 UTC, Gopan wrote:
 On Wednesday, 11 May 2016 at 17:15:29 UTC, Kagamin wrote:
 https://dpaste.dzfl.pl/46f24c3def62
It gave compilation error because, one of the parameters of the comma() template in your code is void. Currently, does D support void as a type of an expression separated by comma?
Yes, see line 8.
May 12 2016
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 5/11/16 1:10 PM, Kagamin wrote:
 On Wednesday, 11 May 2016 at 16:46:48 UTC, Nick Treleaven wrote:
 In places where the comma operator does help,  use a
 comma(expr,result) template function, implemented here:
 http://forum.dlang.org/post/ngslcl$otg$1 digitalmars.com
May not always work: https://dpaste.dzfl.pl/1ea0df70787b
Yep, that is true. I also found deep in the discussions of previous kill-comma-operator PRs, others have thought of the solution I came up with. One possible "fix" would be to make all the parameters lazy, and evaluate them all before returning the last :) (Thanks Vladimir for showing us that possibility). But I'm not even going to try and implement that, it's horrific. -Steve
May 12 2016
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/11/16 7:46 PM, Nick Treleaven wrote:
 In places where the comma operator does help,  use a comma(expr,result)
 template function
Better yet instead of e1, e2, e3 type { e1; e2; return e3; }() Andrei
May 12 2016
prev sibling parent Claude <no no.no> writes:
 int x;
 while( scanf("%d", &x),  x!= 0) // until user input 0.
 {
    //do something with x
 }

 Does anybody think that this is a useful case of comma operator?
I think it's not a safe way to write code. The only time I use comma in C (outside for loops) is when I write some clever macros to do some boilerplate. Comma-operator may have some use in C, but I reckon it makes no sense in D and adds some confusion. So I join the majority: KILL IT!! (WITH ACID...)
May 12 2016
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Before we get lost in the discussions, let's act on this by disallowing 
taking the result of the comma operator. Yes there is potential breakage 
(via typeof as Timon noted) but it's likely to be minimal. Once we have 
that in place we have more options. Thx! -- Andrei
May 12 2016
parent reply Mathias Lang <mathias.lang sociomantic.com> writes:
On Thursday, 12 May 2016 at 10:29:36 UTC, Andrei Alexandrescu 
wrote:
 Before we get lost in the discussions, let's act on this by 
 disallowing taking the result of the comma operator. Yes there 
 is potential breakage (via typeof as Timon noted) but it's 
 likely to be minimal. Once we have that in place we have more 
 options. Thx! -- Andrei
Just a quick update on that topic: using the return of a comma operator now yield a deprecation message (using DMD ~master). This will be part of 2.072.0. Thanks everyone for your feedback !
Jun 10 2016
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/10/16 1:02 PM, Mathias Lang wrote:
 On Thursday, 12 May 2016 at 10:29:36 UTC, Andrei Alexandrescu wrote:
 Before we get lost in the discussions, let's act on this by
 disallowing taking the result of the comma operator. Yes there is
 potential breakage (via typeof as Timon noted) but it's likely to be
 minimal. Once we have that in place we have more options. Thx! -- Andrei
Just a quick update on that topic: using the return of a comma operator now yield a deprecation message (using DMD ~master). This will be part of 2.072.0. Thanks everyone for your feedback !
That's terrific. Thank you!! -- Andrei
Jun 10 2016
parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Fri, Jun 10, 2016 at 05:11:59PM +0000, Andrei Alexandrescu via Digitalmars-d
wrote:
 On 6/10/16 1:02 PM, Mathias Lang wrote:
 On Thursday, 12 May 2016 at 10:29:36 UTC, Andrei Alexandrescu wrote:
 Before we get lost in the discussions, let's act on this by
 disallowing taking the result of the comma operator. Yes there is
 potential breakage (via typeof as Timon noted) but it's likely to
 be minimal. Once we have that in place we have more options. Thx!
 -- Andrei
Just a quick update on that topic: using the return of a comma operator now yield a deprecation message (using DMD ~master). This will be part of 2.072.0. Thanks everyone for your feedback !
That's terrific. Thank you!! -- Andrei
Hooray! One small step in the right direction of killing off the comma operator for good. T -- Those who've learned LaTeX swear by it. Those who are learning LaTeX swear at it. -- Pete Bleackley
Jun 10 2016