digitalmars.D - "using the result of a comma expression is not allowed"
- Don Allen (12/12) Apr 21 I just ran across "using the result of a comma expression is not
- Paul Backus (9/21) Apr 21 IIRC the rationale here was to reserve the comma operator for use
- Dukc (20/32) Apr 21 The comma expression used to work just like in C several years
- Steven Schveighoffer (20/32) Apr 21 Comma expressions can make code with typos be accepted causing
- Don Allen (19/53) Apr 21 Thank you both for your useful replies and I understand why D has
- Don Allen (5/15) Apr 21 I should have noted that I am not talking about lambdas in
- bachmeier (4/11) Apr 21 I agree, and it's more than just those two languages, so I view
- Timon Gehr (13/18) Apr 21 That is just one part of the rationale (that is probably on top of
- Don Allen (30/53) Apr 22 Excuse me. I am an ordinary user of D (you know, the kinds of
- Timon Gehr (7/64) Apr 22 Because your response was to a post that gave a more nuanced and more
I just ran across "using the result of a comma expression is not allowed" in a situation where I used a comma expression as I would in C, expecting its value to be the value of the right-most expression. While D's language document is accurate in explaining how the comma expression is treated in D in 11.5, that treatment conflicts with 11.1: "Expressions are used to compute values with a resulting type. These values can then be assigned, tested, or ignored. Expressions can also have side effects." This restriction makes no sense to me, nor does calling this an "expression" if you can't use its value.
Apr 21
On Sunday, 21 April 2024 at 16:28:47 UTC, Don Allen wrote:I just ran across "using the result of a comma expression is not allowed" in a situation where I used a comma expression as I would in C, expecting its value to be the value of the right-most expression. While D's language document is accurate in explaining how the comma expression is treated in D in 11.5, that treatment conflicts with 11.1: "Expressions are used to compute values with a resulting type. These values can then be assigned, tested, or ignored. Expressions can also have side effects." This restriction makes no sense to me, nor does calling this an "expression" if you can't use its value.IIRC the rationale here was to reserve the comma operator for use in tuple expressions (like in Python). If you the behavior of a C-style comma expression, you can use a function literal: // `e1, e2` becomes () { e1; return e2; }() If `e2` is an lvalue, you may want to prefix the function literal with `ref`.
Apr 21
On Sunday, 21 April 2024 at 16:28:47 UTC, Don Allen wrote:I just ran across "using the result of a comma expression is not allowed" in a situation where I used a comma expression as I would in C, expecting its value to be the value of the right-most expression. While D's language document is accurate in explaining how the comma expression is treated in D in 11.5, that treatment conflicts with 11.1: "Expressions are used to compute values with a resulting type. These values can then be assigned, tested, or ignored. Expressions can also have side effects." This restriction makes no sense to me, nor does calling this an "expression" if you can't use its value.The comma expression used to work just like in C several years ago. Using it's value was disallowed at some point because there have been talks about using the syntax for something else - tuples if I recall correctly. The idea was that this way we don't end up changing what a syntax does overnight, it will be disabled for a few years in between so there can be a deprecation period. Apparently the spec wasn't corrected completely to reflect the new rules. It is an expression in a grammatical sense, meaning you can put a comma expression anywhere you would put a side-effecting expression. For example: ```D for(;;comma(), expression()) condition? another(), comma(), expression(): (yet(), another(), expression()); ``` ...well it seems the compiler rejects the conditional here (otherwise this is fine). That's arguably a bug, after all it's not using the result in any way.
Apr 21
On Sunday, 21 April 2024 at 16:28:47 UTC, Don Allen wrote:I just ran across "using the result of a comma expression is not allowed" in a situation where I used a comma expression as I would in C, expecting its value to be the value of the right-most expression. While D's language document is accurate in explaining how the comma expression is treated in D in 11.5, that treatment conflicts with 11.1: "Expressions are used to compute values with a resulting type. These values can then be assigned, tested, or ignored. Expressions can also have side effects." This restriction makes no sense to me, nor does calling this an "expression" if you can't use its value.Comma expressions can make code with typos be accepted causing confusing problems. The compromise, since comma expressions are useful in the update section of `for` loops, was to simply disallow using the value of the expression. In my experience with C, by far the most common use of comma expressions is to expand macros in expression context. Obviously, we don't need that in D, you can do the same thing with a lambda in D. A very notorious misuse of comma expressions was in Andrei's "The D Programming Language" book, where it was stated that `synchronized(A, B)` would protect the following block by locking `A` and `B` in the proper sequence. However, this feature was not implemented, instead, `A, B` was a comma expression, and only `B` was locked. As also noted by others, we may reuse the comma expression syntax for tuples somehow, which only works if you can't use comma expressions to mean "only the last thing". -Steve
Apr 21
Thank you both for your useful replies and I understand why D has parted company with C in this area. But I maintain that the documentation is in conflict with itself and should be fixed (11.1 could note that there are exceptions, such as comma expressions). And I think it's bad practice to support a hobbled version of a common construct in anticipation of a use of the same syntax that hasn't happened yet and has been in the pipeline for years. I am also not about to re-write my code using lambdas. It's hackish workaround for a defect in the language, in my opinion. And this whole discussion brings up the issue, for me, that 'if' and blocks are not expressions that can yield values. Both Rust and Zig support this. The separate and redundant conditional statement and expression in D is a holdover from C. I think this was a mistake in C and a bigger mistake in D, since we know more now about language design than when Dennis Ritchie designed C about 55 years ago. On Sunday, 21 April 2024 at 18:31:55 UTC, Steven Schveighoffer wrote:On Sunday, 21 April 2024 at 16:28:47 UTC, Don Allen wrote:I just ran across "using the result of a comma expression is not allowed" in a situation where I used a comma expression as I would in C, expecting its value to be the value of the right-most expression. While D's language document is accurate in explaining how the comma expression is treated in D in 11.5, that treatment conflicts with 11.1: "Expressions are used to compute values with a resulting type. These values can then be assigned, tested, or ignored. Expressions can also have side effects." This restriction makes no sense to me, nor does calling this an "expression" if you can't use its value.Comma expressions can make code with typos be accepted causing confusing problems. The compromise, since comma expressions are useful in the update section of `for` loops, was to simply disallow using the value of the expression. In my experience with C, by far the most common use of comma expressions is to expand macros in expression context. Obviously, we don't need that in D, you can do the same thing with a lambda in D. A very notorious misuse of comma expressions was in Andrei's "The D Programming Language" book, where it was stated that `synchronized(A, B)` would protect the following block by locking `A` and `B` in the proper sequence. However, this feature was not implemented, instead, `A, B` was a comma expression, and only `B` was locked. As also noted by others, we may reuse the comma expression syntax for tuples somehow, which only works if you can't use comma expressions to mean "only the last thing". -Steve
Apr 21
On Sunday, 21 April 2024 at 19:16:03 UTC, Don Allen wrote:Thank you both for your useful replies and I understand why D has parted company with C in this area. But I maintain that the documentation is in conflict with itself and should be fixed (11.1 could note that there are exceptions, such as comma expressions). And I think it's bad practice to support a hobbled version of a common construct in anticipation of a use of the same syntax that hasn't happened yet and has been in the pipeline for years. I am also not about to re-write my code using lambdas. It's hackish workaround for a defect in the language, in my opinion.I should have noted that I am not talking about lambdas in general -- just as a substitute in this instance for blocks returning values. I have written a lot of Lisp and Scheme over many years.
Apr 21
On Sunday, 21 April 2024 at 19:16:03 UTC, Don Allen wrote:And this whole discussion brings up the issue, for me, that 'if' and blocks are not expressions that can yield values. Both Rust and Zig support this. The separate and redundant conditional statement and expression in D is a holdover from C. I think this was a mistake in C and a bigger mistake in D, since we know more now about language design than when Dennis Ritchie designed C about 55 years ago.I agree, and it's more than just those two languages, so I view this as a small barrier to D. It's one of those things that might not be major, but it does get annoying.
Apr 21
On 4/21/24 21:16, Don Allen wrote:And I think it's bad practice to support a hobbled version of a common construct in anticipation of a use of the same syntax that hasn't happened yet and has been in the pipeline for years.That is just one part of the rationale (that is probably on top of people's mind now as there has been some recent movement on tuples). https://dlang.org/deprecate#Using%20the%20result%20of%20a%20comma%20expression In any case, I don't understand why you focus on the tuple use case. The main reason the comma operator was restricted was to avoid accidental uses. Freeing up the syntax for something that is actually useful is just a nice side effect.I am also not about to re-write my code using lambdas. It's hackish workaround for a defect in the language, in my opinion.There are many ways to write any given piece of code and the variant with the comma operator is hardly ever the best one.I think this was a mistake in C and a bigger mistake in D, since we know more now about language design than when Dennis Ritchie designed C about 55 years ago.One of the things we know now is that comma expressions were a bad design of syntax. We should probably just have something like `let statement in expression` expressions instead.
Apr 21
On Sunday, 21 April 2024 at 23:32:21 UTC, Timon Gehr wrote:On 4/21/24 21:16, Don Allen wrote:Excuse me. I am an ordinary user of D (you know, the kinds of people the project would like to attract? One way to torpedo that is to behave like an OpenBSD developer), not someone who has participated in, or followed the history of, the language's development. I focused on tuples because it came up repeatedly in the responses to my original post. You note that yourself above. So I don't understand why you didn't understand. The main reason the comma operator was restricted was toAnd I think it's bad practice to support a hobbled version of a common construct in anticipation of a use of the same syntax that hasn't happened yet and has been in the pipeline for years.That is just one part of the rationale (that is probably on top of people's mind now as there has been some recent movement on tuples). https://dlang.org/deprecate#Using%20the%20result%20of%20a%20comma%20expression In any case, I don't understand why you focus on the tuple use case.avoid accidental uses. Freeing up the syntax for something that is actually useful is just a nice side effect.You haven't seen the situation where I attempted to use it as I would have in C, have you?I am also not about to re-write my code using lambdas. It's hackish workaround for a defect in the language, in my opinion.There are many ways to write any given piece of code and the variant with the comma operator is hardly ever the best one.You may have missed my point, which was that value-returning block expressions are a better way than comma expressions to allow multi-statement sequences to provide a value, as in Rust: ```` let foo:i64 = if predicate { stmta1; stmta2; expra1 } else { stmtb1; stmtb2; exprb1 }; ```` Something similar exists in Zig, though I don't think their syntax is as elegant as Rust's in this case.I think this was a mistake in C and a bigger mistake in D, since we know more now about language design than when Dennis Ritchie designed C about 55 years ago.One of the things we know now is that comma expressions were a bad design of syntax. We should probably just have something like `let statement in expression` expressions instead.
Apr 22
On 4/22/24 15:21, Don Allen wrote:On Sunday, 21 April 2024 at 23:32:21 UTC, Timon Gehr wrote:No offense had been taken.On 4/21/24 21:16, Don Allen wrote:Excuse me. ...And I think it's bad practice to support a hobbled version of a common construct in anticipation of a use of the same syntax that hasn't happened yet and has been in the pipeline for years.That is just one part of the rationale (that is probably on top of people's mind now as there has been some recent movement on tuples). https://dlang.org/deprecate#Using%20the%20result%20of%20a%20comma%20expression In any case, I don't understand why you focus on the tuple use case.I focused on tuples because it came up repeatedly in the responses to my original post. You note that yourself above. So I don't understand why you didn't understand. ...Because your response was to a post that gave a more nuanced and more complete answer, with the proper weight given to the different arguments.Feel free to share.... There are many ways to write any given piece of code and the variant with the comma operator is hardly ever the best one.You haven't seen the situation where I attempted to use it as I would have in C, have you? ...I did not.You may have missed my point,I think this was a mistake in C and a bigger mistake in D, since we know more now about language design than when Dennis Ritchie designed C about 55 years ago.One of the things we know now is that comma expressions were a bad design of syntax. We should probably just have something like `let statement in expression` expressions instead.which was that value-returning block expressions are a better way than comma expressions to allow multi-statement sequences to provide a value, as in Rust: ```` let foo:i64 = if predicate { stmta1; stmta2; expra1 } else { stmtb1; stmtb2; exprb1 }; ```` Something similar exists in Zig, though I don't think their syntax is as elegant as Rust's in this case.This does not clash with tuple syntax.
Apr 22