digitalmars.D - The Comma Operator's Deprecation Can't Come Soon Enough
- Meta (23/23) Jul 15 2014 Spot the bug:
- Martin Krejcirik (2/4) Jul 15 2014 What is unexpected about that ?
- Meta (5/9) Jul 15 2014 It makes the behaviour of the template that's unexpected.
- bearophile (4/5) Jul 15 2014 We can start killing those commas in D 2.067 :-)
- H. S. Teoh via Digitalmars-d (7/12) Jul 15 2014 [...]
- Frustrated (6/29) Jul 15 2014 This isn't a bug! It's a logic mistake.
- Meta (6/11) Jul 15 2014 Yes, I wasn't thinking and typed "typeof(R.init.front, depth -
- Andrej Mitrovic via Digitalmars-d (2/5) Jul 15 2014 Well yeah, real world programmers make mistakes.
- Jane Doe (15/21) Jul 15 2014 So, you wanna nerf everything that could produce the wrong
- John Colvin (4/27) Jul 15 2014 The reason for getting rid of it is because it's borderline
- Martin Krejcirik (4/7) Jul 15 2014 I find the comma op useful somemtimes. This example shows
- H. S. Teoh via Digitalmars-d (5/9) Jul 15 2014 Example?
- Martin Krejcirik (18/19) Jul 15 2014 For loop with multiple variables and various one liners of
- Meta (6/27) Jul 15 2014 From the previous discussion, everyone agreed that the loop
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (13/34) Jul 15 2014 Is the following the intended equivalent?
- John Colvin (23/44) Jul 15 2014 cute, but I'd still prefer this
- Brian Schott (4/7) Jul 15 2014 http://forum.dlang.org/thread/xmqzrgysgxdmqrnfpxdq@forum.dlang.org
- Martin Krejcirik (7/9) Jul 15 2014 You are right for the 'final' code, but the point of my example
- bearophile (4/7) Jul 15 2014 If I find code like yours, I refactor it ASAP :-)
- H. S. Teoh via Digitalmars-d (11/21) Jul 15 2014 Not true:
- H. S. Teoh via Digitalmars-d (10/28) Jul 15 2014 [...]
- bearophile (8/12) Jul 15 2014 Please shows us all the cases you can think of (or coming from
- bearophile (20/24) Jul 15 2014 A smarter question is: How to reduce the number of bugs in D code
- Andrej Mitrovic via Digitalmars-d (3/5) Jul 15 2014 No but maybe we should reduce the number of different accounts a
- Israel Rodriguez (2/25) Jul 15 2014 Nuh uh...The comma operator is too valuable to loose...
- H. S. Teoh via Digitalmars-d (6/7) Jul 15 2014 Please cite an example where it is "valuable"?
- Tofu Ninja (4/10) Jul 15 2014 Yes please, I legitimately can't think of any use case. I don't
- Meta (2/5) Jul 15 2014 C compatibility as far as I know.
- H. S. Teoh via Digitalmars-d (28/42) Jul 15 2014 I don't think it was "introduced", probably just inherited from C.
- Yota (8/22) Jul 23 2014 It appears Microsoft is musing the idea of adding this operator
- sigod (3/10) Jul 23 2014 `(var x = Foo(); Write(x); x * x)`
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (16/28) Jul 23 2014 Reminds me... Is everybody aware of D's for syntax?
- H. S. Teoh via Digitalmars-d (8/27) Jul 23 2014 [...]
- Meta (5/20) Jul 23 2014 What in the hell is this? Is the { int i = 42; ... } block
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (15/46) Jul 23 2014 And totally legal:
- Yota (3/14) Jul 23 2014 Fairly consistent with functional languages like F#, however.
Spot the bug: template flattenedType(R, uint depth = uint.max) if (isInputRange!R) { static if (depth > 0) { static if (!isInputRange!(typeof(R.init.front))) { alias flattenedType = typeof(R.init.front, depth - 1); } else { alias flattenedType = flattenedType!(typeof(R.init.front), depth - 1); } } else { alias flattenedType = typeof(R.init.front); } } I'll give you a hint: the bug causes flattenedType!R to always returned uint.
Jul 15 2014
On Tuesday, 15 July 2014 at 08:01:40 UTC, Meta wrote:I'll give you a hint: the bug causes flattenedType!R to always returned uint.What is unexpected about that ?
Jul 15 2014
On Tuesday, 15 July 2014 at 08:20:34 UTC, Martin Krejcirik wrote:On Tuesday, 15 July 2014 at 08:01:40 UTC, Meta wrote:It makes the behaviour of the template that's unexpected. flattenedType!(float[][][][]) returning uint is unexpected. But that's not the problem. The problem is a hard (IMO) to spot bug caused by the comma operator.I'll give you a hint: the bug causes flattenedType!R to always returned uint.What is unexpected about that ?
Jul 15 2014
Meta:Spot the bug:We can start killing those commas in D 2.067 :-) Bye, bearophile
Jul 15 2014
On Tue, Jul 15, 2014 at 08:42:17AM +0000, bearophile via Digitalmars-d wrote:Meta:[...] Is that the agreed-on schedule? I'd love to see the comma operator go, too, but I don't recall the core devs agreeing on a deprecation date. T -- There's light at the end of the tunnel. It's the oncoming train.Spot the bug:We can start killing those commas in D 2.067 :-)
Jul 15 2014
On Tuesday, 15 July 2014 at 08:01:40 UTC, Meta wrote:Spot the bug: template flattenedType(R, uint depth = uint.max) if (isInputRange!R) { static if (depth > 0) { static if (!isInputRange!(typeof(R.init.front))) { alias flattenedType = typeof(R.init.front, depth - 1); } else { alias flattenedType = flattenedType!(typeof(R.init.front), depth - 1); } } else { alias flattenedType = typeof(R.init.front); } } I'll give you a hint: the bug causes flattenedType!R to always returned uint.This isn't a bug! It's a logic mistake. Why the heck would you have such a line anyways? alias flattenedType = typeof(R.init.front, depth - 1); The 2nd "argument" to typeof makes no sense. It shouldn't be on that line at all. Total fail by the programmer.
Jul 15 2014
On Tuesday, 15 July 2014 at 16:01:37 UTC, Frustrated wrote:This isn't a bug! It's a logic mistake. Why the heck would you have such a line anyways? alias flattenedType = typeof(R.init.front, depth - 1); The 2nd "argument" to typeof makes no sense. It shouldn't be on that line at all. Total fail by the programmer.Yes, I wasn't thinking and typed "typeof(R.init.front, depth - 1)" because just a moment before a few lines down I typed "flattenedType!(typeof(R.init.front), depth - 1)". Once the comma operator is deprecated, however, it will be impossible to make this kind of careless mistake.
Jul 15 2014
On 7/15/14, Frustrated via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Tuesday, 15 July 2014 at 08:01:40 UTC, Meta wrote: The 2nd "argument" to typeof makes no sense. It shouldn't be on that line at all. Total fail by the programmer.Well yeah, real world programmers make mistakes.
Jul 15 2014
On Tuesday, 15 July 2014 at 16:16:19 UTC, Andrej Mitrovic via Digitalmars-d wrote:On 7/15/14, Frustrated via Digitalmars-d <digitalmars-d puremagic.com> wrote:So, you wanna nerf everything that could produce the wrong behavior? Should be reduce the speed limit to 5mph because cars can kill people? There is nothing in this example that shows the comma operator is evil. Any programming language as a plethora of similar issues. Should we get rid of || && etc because one might forget to double it? e.g., if (x | y) when one meant if (x || y)? It's not the languages fault if you can't pay attention to what you are doing! The code looks like he copy and pasted the 2nd alias line and forgot to remove the depth part. Again, this speaks nothing about the comma operator but about the programmer.On Tuesday, 15 July 2014 at 08:01:40 UTC, Meta wrote: The 2nd "argument" to typeof makes no sense. It shouldn't be on that line at all. Total fail by the programmer.Well yeah, real world programmers make mistakes.
Jul 15 2014
On Tuesday, 15 July 2014 at 16:45:02 UTC, Jane Doe wrote:On Tuesday, 15 July 2014 at 16:16:19 UTC, Andrej Mitrovic via Digitalmars-d wrote:The reason for getting rid of it is because it's borderline useless. It causes more accidental bugs than it enables deliberate uses.On 7/15/14, Frustrated via Digitalmars-d <digitalmars-d puremagic.com> wrote:So, you wanna nerf everything that could produce the wrong behavior? Should be reduce the speed limit to 5mph because cars can kill people? There is nothing in this example that shows the comma operator is evil. Any programming language as a plethora of similar issues. Should we get rid of || && etc because one might forget to double it? e.g., if (x | y) when one meant if (x || y)? It's not the languages fault if you can't pay attention to what you are doing! The code looks like he copy and pasted the 2nd alias line and forgot to remove the depth part. Again, this speaks nothing about the comma operator but about the programmer.On Tuesday, 15 July 2014 at 08:01:40 UTC, Meta wrote: The 2nd "argument" to typeof makes no sense. It shouldn't be on that line at all. Total fail by the programmer.Well yeah, real world programmers make mistakes.
Jul 15 2014
The reason for getting rid of it is because it's borderline useless. It causes more accidental bugs than it enables deliberate uses.I find the comma op useful somemtimes. This example shows absolutely nothing of comma wrongdoing. If anything, there could be a warning for passing signed value to unsigned argument (that caught me, not comma).
Jul 15 2014
On Tue, Jul 15, 2014 at 05:03:21PM +0000, Martin Krejcirik via Digitalmars-d wrote:Example? T -- Don't drink and derive. Alcohol and algebra don't mix.The reason for getting rid of it is because it's borderline useless. It causes more accidental bugs than it enables deliberate uses.I find the comma op useful somemtimes.
Jul 15 2014
Example?For loop with multiple variables and various one liners of questionable utility aside: import std.stdio; bool funk() { static int count; return ++count > 1 ? true : false; } void main() { bool flag = false; if (flag && funk) writeln("a"); else if (flag=true, flag && funk) writeln("b"); else if (flag && funk) writeln("c"); }
Jul 15 2014
On Tuesday, 15 July 2014 at 18:08:15 UTC, Martin Krejcirik wrote:From the previous discussion, everyone agreed that the loop variable usage would not be deprecated, even if the comma operator were deprecated elsewhere. That's pretty much the only place it's really useful. As for those one-liners, "questionable utility" is the keyword (and also "probably buggy").Example?For loop with multiple variables and various one liners of questionable utility aside: import std.stdio; bool funk() { static int count; return ++count > 1 ? true : false; } void main() { bool flag = false; if (flag && funk) writeln("a"); else if (flag=true, flag && funk) writeln("b"); else if (flag && funk) writeln("c"); }
Jul 15 2014
On 07/15/2014 11:08 AM, Martin Krejcirik wrote:Is the following the intended equivalent? if (flag && funk) writeln("a"); else { flag=true; if (flag && funk) writeln("b"); else if (flag && funk) writeln("c"); } If I had to ask nobody should use the version you wrote! ;) AliExample?For loop with multiple variables and various one liners of questionable utility aside: import std.stdio; bool funk() { static int count; return ++count > 1 ? true : false; } void main() { bool flag = false; if (flag && funk) writeln("a"); else if (flag=true, flag && funk) writeln("b"); else if (flag && funk) writeln("c"); }
Jul 15 2014
On Tuesday, 15 July 2014 at 18:08:15 UTC, Martin Krejcirik wrote:cute, but I'd still prefer this void main() { bool flag = false; if (flag && funk) writeln("a"); else { flag = true; if (flag && funk) writeln("b"); else if (flag && funk) writeln("c"); } } and not just because I don't like the comma. I'd say it's generally bad practice to hide that write to `flag` inside the if condition. By spreading it out it is clear that the different conditions are evaluated with different external state. The comma operators entire job is to inject state changes where the reader doesn't expect them. It's a misfeature of C that we've sadly inherited and should rid ourselves from.Example?For loop with multiple variables and various one liners of questionable utility aside: import std.stdio; bool funk() { static int count; return ++count > 1 ? true : false; } void main() { bool flag = false; if (flag && funk) writeln("a"); else if (flag=true, flag && funk) writeln("b"); else if (flag && funk) writeln("c"); }
Jul 15 2014
On Tuesday, 15 July 2014 at 18:50:08 UTC, John Colvin wrote:The comma operators entire job is to inject state changes where the reader doesn't expect them. It's a misfeature of C that we've sadly inherited and should rid ourselves from.http://forum.dlang.org/thread/xmqzrgysgxdmqrnfpxdq forum.dlang.org The comma operator will be harder to fix than this bug in the exception handling grammar, and I couldn't even get that approved.
Jul 15 2014
On Tuesday, 15 July 2014 at 18:50:08 UTC, John Colvin wrote:and not just because I don't like the comma. I'd say it's generally bad practice to hide that write to `flag` inside theYou are right for the 'final' code, but the point of my example is, that I can move the flag to another if and don't have to change anything else. Also an assignment is not allowed in a condition and without the comma operator, it wouldn't be possible at all. That's way too restrictive.
Jul 15 2014
Martin Krejcirik:Also an assignment is not allowed in a condition and without the comma operator, it wouldn't be possible at all. That's way too restrictive.If I find code like yours, I refactor it ASAP :-) Bye, bearophile
Jul 15 2014
On Tue, Jul 15, 2014 at 07:16:17PM +0000, Martin Krejcirik via Digitalmars-d wrote:On Tuesday, 15 July 2014 at 18:50:08 UTC, John Colvin wrote:Not true: T* ptr; if ((ptr = getPtr()) !is null) { ... } Nevertheless, it's a bad idea to have side effects in if-conditions. It makes code hard to follow, and is a cosy place for subtle bugs to hide. T -- Never trust an operating system you don't have source for! -- Martin Schulzeand not just because I don't like the comma. I'd say it's generally bad practice to hide that write to `flag` inside theYou are right for the 'final' code, but the point of my example is, that I can move the flag to another if and don't have to change anything else. Also an assignment is not allowed in a condition and without the comma operator, it wouldn't be possible at all. That's way too restrictive.
Jul 15 2014
On Tue, Jul 15, 2014 at 12:46:04PM -0700, H. S. Teoh via Digitalmars-d wrote:On Tue, Jul 15, 2014 at 07:16:17PM +0000, Martin Krejcirik via Digitalmars-d wrote:[...] Better yet, this syntax is supported: if (auto ptr = getPtr()) { // ptr is not null here } T -- Real men don't take backups. They put their source on a public FTP-server and let the world mirror it. -- Linus TorvaldsOn Tuesday, 15 July 2014 at 18:50:08 UTC, John Colvin wrote:Not true: T* ptr; if ((ptr = getPtr()) !is null) { ... }and not just because I don't like the comma. I'd say it's generally bad practice to hide that write to `flag` inside theYou are right for the 'final' code, but the point of my example is, that I can move the flag to another if and don't have to change anything else. Also an assignment is not allowed in a condition and without the comma operator, it wouldn't be possible at all. That's way too restrictive.
Jul 15 2014
Martin Krejcirik:I find the comma op useful somemtimes.Please shows us all the cases you can think of (or coming from your own code, or coming from the Web) where you think it's useful.This example shows absolutely nothing of comma wrongdoing.See my precedent answer.If anything, there could be a warning for passing signed value to unsigned argument (that caught me, not comma).That's an OffTopic battle, for another day :-) Bye, bearophile
Jul 15 2014
Jane Doe:So, you wanna nerf everything that could produce the wrong behavior?A smarter question is: How to reduce the number of bugs in D code decreasing the language functionality only very little, and keeping the language handy (or making it even more handy)?There is nothing in this example that shows the comma operator is evil.Typeof takes an argument, but two were given: typeof(R.init.front, depth - 1) The fact that in truth only one argument was given is caused by the comma operator that has both the semantics of sequence (when you define multiple variables, multiple enum items, multiple function arguments, multiple template arguments, and so on), and the not often useful semantics of sequencing of expressions with side effects, plus keeping the result of the last one. If you restrict the usage of commas, disallowing that second semantics, that code causes a compilation error. The idea of killing the comma operator was discussed at length in past threads. I suggest to deprecate it, and eventually open the syntax to better usages (tuples and pattern matching, making D quite more handy than now). Bye, bearophile
Jul 15 2014
On 7/15/14, Jane Doe via Digitalmars-d <digitalmars-d puremagic.com> wrote:Should be reduce the speed limit to 5mph because cars can kill people?No but maybe we should reduce the number of different accounts a single person can use to troll around these forums.
Jul 15 2014
On Tuesday, 15 July 2014 at 08:01:40 UTC, Meta wrote:Spot the bug: template flattenedType(R, uint depth = uint.max) if (isInputRange!R) { static if (depth > 0) { static if (!isInputRange!(typeof(R.init.front))) { alias flattenedType = typeof(R.init.front, depth - 1); } else { alias flattenedType = flattenedType!(typeof(R.init.front), depth - 1); } } else { alias flattenedType = typeof(R.init.front); } } I'll give you a hint: the bug causes flattenedType!R to always returned uint.Nuh uh...The comma operator is too valuable to loose...
Jul 15 2014
On Tue, Jul 15, 2014 at 04:52:34PM +0000, Israel Rodriguez via Digitalmars-d wrote: [...]Nuh uh...The comma operator is too valuable to loose...Please cite an example where it is "valuable"? T -- Without outlines, life would be pointless.
Jul 15 2014
On Tuesday, 15 July 2014 at 17:09:14 UTC, H. S. Teoh via Digitalmars-d wrote:On Tue, Jul 15, 2014 at 04:52:34PM +0000, Israel Rodriguez via Digitalmars-d wrote: [...]Yes please, I legitimately can't think of any use case. I don't understand why was this was ever introduced to D? What is the use?Nuh uh...The comma operator is too valuable to loose...Please cite an example where it is "valuable"? T
Jul 15 2014
On Tuesday, 15 July 2014 at 17:26:12 UTC, Tofu Ninja wrote:Yes please, I legitimately can't think of any use case. I don't understand why was this was ever introduced to D? What is the use?C compatibility as far as I know.
Jul 15 2014
On Tue, Jul 15, 2014 at 05:26:11PM +0000, Tofu Ninja via Digitalmars-d wrote:On Tuesday, 15 July 2014 at 17:09:14 UTC, H. S. Teoh via Digitalmars-d wrote:I don't think it was "introduced", probably just inherited from C. The traditional justification for it in C is to allow writing things like: for (i=0, j=0; i < 10 && j < 20; i++, j+=2) { ... } However, this can be easily implemented as special syntax for for-loops; it needn't be a general syntax that can be used everywhere. There are some other marginal use cases where it saves a tiny bit of typing, but really, in this day and age, the only time that's really *needed* is when submitting entries to the IOCCC. :-P Of course, then C++ came along and made the whole thing a whole order of magnitude worse, by introducing operator,(), which leads to nastiness like: void func(Array<2,int> matrix) { matrix = 1, 2, 3, 4, 5, 6, 7, 8, 9; } which looks cool until you think about it some more, and then you realize that there are just so many ways in which this can go really, horribly wrong. Personally, I can't wait for the comma operator to be killed off for good. Preferably with extreme prejudice. T -- Try to keep an open mind, but not so open your brain falls out. -- thebozOn Tue, Jul 15, 2014 at 04:52:34PM +0000, Israel Rodriguez via Digitalmars-d wrote: [...]Yes please, I legitimately can't think of any use case. I don't understand why was this was ever introduced to D? What is the use?Nuh uh...The comma operator is too valuable to loose...Please cite an example where it is "valuable"? T
Jul 15 2014
On Tuesday, 15 July 2014 at 17:26:12 UTC, Tofu Ninja wrote:On Tuesday, 15 July 2014 at 17:09:14 UTC, H. S. Teoh via Digitalmars-d wrote:It appears Microsoft is musing the idea of adding this operator going with a semicolon. https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status&referringTitle=Documentation I dislike the comma operator as well, but would there be any problems if it were a semicolon instead? I think the new symbol would fit well in for() loops.On Tue, Jul 15, 2014 at 04:52:34PM +0000, Israel Rodriguez via Digitalmars-d wrote: [...]Yes please, I legitimately can't think of any use case. I don't understand why was this was ever introduced to D? What is the use?Nuh uh...The comma operator is too valuable to loose...Please cite an example where it is "valuable"? T
Jul 23 2014
On Wednesday, 23 July 2014 at 17:25:43 UTC, Yota wrote:It appears Microsoft is musing the idea of adding this operator going with a semicolon. https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status&referringTitle=Documentation I dislike the comma operator as well, but would there be any problems if it were a semicolon instead? I think the new symbol would fit well in for() loops.`(var x = Foo(); Write(x); x * x)` Looks kinda strange.
Jul 23 2014
On 07/23/2014 10:59 AM, sigod wrote:On Wednesday, 23 July 2014 at 17:25:43 UTC, Yota wrote:Reminds me... Is everybody aware of D's for syntax? import std.stdio; void main() { for ( { int i = 42; double d = 1.5; string s = "hello"; } i < 100; i *= 2) { writefln("In the loop with %s %s %s", i, d, s); } } :) Also note the absence of ; before the loop condition. Aliand VB.Net. Only instead of it being a comma, they're going with a semicolon. https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status&referringTitle=Documentation I dislike the comma operator as well, but would there be any problems if it were a semicolon instead? I think the new symbol would fit well in for() loops.`(var x = Foo(); Write(x); x * x)` Looks kinda strange.
Jul 23 2014
On Wed, Jul 23, 2014 at 12:04:52PM -0700, Ali Çehreli via Digitalmars-d wrote: [...]Reminds me... Is everybody aware of D's for syntax? import std.stdio; void main() { for ( { int i = 42; double d = 1.5; string s = "hello"; } i < 100; i *= 2) { writefln("In the loop with %s %s %s", i, d, s); } } :) Also note the absence of ; before the loop condition.[...] :-O Arghhhh... my eyes are bleeding from this nasty syntax... :-( T -- This sentence is false.
Jul 23 2014
On Wednesday, 23 July 2014 at 19:04:52 UTC, Ali Çehreli wrote:Reminds me... Is everybody aware of D's for syntax? import std.stdio; void main() { for ( { int i = 42; double d = 1.5; string s = "hello"; } i < 100; i *= 2) { writefln("In the loop with %s %s %s", i, d, s); } } :) Also note the absence of ; before the loop condition. AliWhat in the hell is this? Is the { int i = 42; ... } block counted as a lambda or a scope? In that case, why is i still available outside the block in the `i < 100; i *= 2` expressions? I feel like my whole world has been turned upside down.
Jul 23 2014
On 07/23/2014 12:04 PM, Ali Çehreli wrote:On 07/23/2014 10:59 AM, sigod wrote:And totally legal: http://dlang.org/statement.html#ForStatement ForStatement: for ( Initialize Testopt ; Incrementopt ) ScopeStatement Initialize: ; NoScopeNonEmptyStatement <-- THIS NoScopeNonEmptyStatement: NonEmptyStatement BlockStatement <-- THIS BlockStatement: { } { StatementList } <-- THIS AliOn Wednesday, 23 July 2014 at 17:25:43 UTC, Yota wrote:Reminds me... Is everybody aware of D's for syntax? import std.stdio; void main() { for ( { int i = 42; double d = 1.5; string s = "hello"; } i < 100; i *= 2) { writefln("In the loop with %s %s %s", i, d, s); } } :) Also note the absence of ; before the loop condition. Aliand VB.Net. Only instead of it being a comma, they're going with a semicolon. https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status&referringTitle=Documentation I dislike the comma operator as well, but would there be any problems if it were a semicolon instead? I think the new symbol would fit well in for() loops.`(var x = Foo(); Write(x); x * x)` Looks kinda strange.
Jul 23 2014
On Wednesday, 23 July 2014 at 17:59:42 UTC, sigod wrote:On Wednesday, 23 July 2014 at 17:25:43 UTC, Yota wrote:(let x = Foo() in (Write x; x * x))It appears Microsoft is musing the idea of adding this they're going with a semicolon. https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status&referringTitle=Documentation I dislike the comma operator as well, but would there be any problems if it were a semicolon instead? I think the new symbol would fit well in for() loops.`(var x = Foo(); Write(x); x * x)` Looks kinda strange.
Jul 23 2014