digitalmars.dip.ideas - Elvis operator - shortened ternary operator
- Andrey Zherikov (14/14) Mar 26 2025 See [wiki](https://en.wikipedia.org/wiki/Elvis_operator) for
- Dukc (5/19) Mar 28 2025 I believe we already have this!
- matheus. (17/24) Mar 28 2025 I don't think this is what Andrey want, example:
- Dukc (3/14) Mar 28 2025 Oh, I somehow thought that both would return 13. Such a slight
- Andrey Zherikov (3/28) Mar 28 2025 Yes. The main benefit is that `a` is not calculated twice if it's
- Paul Backus (15/29) Mar 28 2025 Library version:
- matheus (12/15) Mar 28 2025 This is a cool alternative, and I think that I saw this before,
- Paul Backus (4/11) Mar 28 2025 Personally I would much, much rather have custom "operators"
- Dejan Lekic (6/9) Apr 01 2025 100%
- Quirin Schroll (5/14) Apr 14 2025 That particular thing should be an operator.
- Quirin Schroll (22/55) Apr 14 2025 That `orElse` cannot preserve value categories. Adding `auto ref`
- Quirin Schroll (33/47) Apr 14 2025 The lowering is actually tricky because the right-hand side ought
See [wiki](https://en.wikipedia.org/wiki/Elvis_operator) for details. Proposed syntax: ```d A ?: B ``` This is equivalent to: ```d auto R = A; // temporary (hidden) variable (cast(bool) R) ? R : B; ``` Semantics: return `A` if it's truthy, or `B` otherwise. Benefit: avoids evaluating if `A` twice which might be a call to some function with side effects.
Mar 26 2025
On Thursday, 27 March 2025 at 00:26:27 UTC, Andrey Zherikov wrote:See [wiki](https://en.wikipedia.org/wiki/Elvis_operator) for details. Proposed syntax: ```d A ?: B ``` This is equivalent to: ```d auto R = A; // temporary (hidden) variable (cast(bool) R) ? R : B; ``` Semantics: return `A` if it's truthy, or `B` otherwise. Benefit: avoids evaluating if `A` twice which might be a call to some function with side effects.I believe we already have this! ```d A || B; ```
Mar 28 2025
On Friday, 28 March 2025 at 09:57:55 UTC, Dukc wrote:On Thursday, 27 March 2025 at 00:26:27 UTC, Andrey Zherikov wrote:See [wiki](https://en.wikipedia.org/wiki/Elvis_operator) forI believe we already have this! ```d A || B; ```I don't think this is what Andrey want, example: import std.stdio; void main(){ int a = 13; int b = 2; auto c = a||b; writeln(c); auto d = a ? a : b; writeln(d); } output: true 13 I think he wants the latter as his link too this matter explain: https://en.wikipedia.org/wiki/Elvis_operator . Matheus.
Mar 28 2025
On Friday, 28 March 2025 at 12:22:24 UTC, matheus. wrote:
void main(){
int a = 13;
int b = 2;
auto c = a||b;
writeln(c);
auto d = a ? a : b;
writeln(d);
}
output:
true
13
Oh, I somehow thought that both would return 13. Such a slight
but annoying difference!
Mar 28 2025
On Friday, 28 March 2025 at 12:22:24 UTC, matheus. wrote:On Friday, 28 March 2025 at 09:57:55 UTC, Dukc wrote:Yes. The main benefit is that `a` is not calculated twice if it's a function like here: `auto d = a() ? a() : b();`On Thursday, 27 March 2025 at 00:26:27 UTC, Andrey Zherikov wrote:See [wiki](https://en.wikipedia.org/wiki/Elvis_operator) forI believe we already have this! ```d A || B; ```I don't think this is what Andrey want, example: import std.stdio; void main(){ int a = 13; int b = 2; auto c = a||b; writeln(c); auto d = a ? a : b; writeln(d); } output: true 13 I think he wants the latter as his link too this matter explain: https://en.wikipedia.org/wiki/Elvis_operator . Matheus.
Mar 28 2025
On Thursday, 27 March 2025 at 00:26:27 UTC, Andrey Zherikov wrote:See [wiki](https://en.wikipedia.org/wiki/Elvis_operator) for details. Proposed syntax: ```d A ?: B ``` This is equivalent to: ```d auto R = A; // temporary (hidden) variable (cast(bool) R) ? R : B; ``` Semantics: return `A` if it's truthy, or `B` otherwise. Benefit: avoids evaluating if `A` twice which might be a call to some function with side effects.Library version: ```d auto orElse(T)(T a, lazy T b) { return a ? a : b; } unittest { string s1 = "hello"; string s2 = null; assert(s1.orElse("goodbye") == "hello"); assert(s2.orElse("goodbye") == "goodbye"); } ```
Mar 28 2025
On Friday, 28 March 2025 at 17:06:56 UTC, Paul Backus wrote:... Library version: ...This is a cool alternative, and I think that I saw this before, maybe (https://code.dlang.org/packages/expected/0.2.3). Now I wonder... you know what would be the thing? - If we could define our own OP, imagine same thing but instead of: A.or(B); <- Shorted version of orElse. A :? B; <- we could define a new unused "op" acting like <,>,&&,||... The difference may look minimal, but the latter really looks nicer, and it's something barely seem in others language. Maybe parsing could be a pain, but anyway just ventilating... Matheus.
Mar 28 2025
On Friday, 28 March 2025 at 19:16:12 UTC, matheus wrote:Now I wonder... you know what would be the thing? - If we could define our own OP, imagine same thing but instead of: A.or(B); <- Shorted version of orElse. A :? B; <- we could define a new unused "op" acting like <,>,&&,||... The difference may look minimal, but the latter really looks nicer, and it's something barely seem in others language.Personally I would much, much rather have custom "operators" written using letters and words, which I can easily read and search for, than with symbols and punctuation marks.
Mar 28 2025
On Friday, 28 March 2025 at 19:47:11 UTC, Paul Backus wrote:Personally I would much, much rather have custom "operators" written using letters and words, which I can easily read and search for, than with symbols and punctuation marks.100% I dream of having something like this: https://kotlinlang.org/docs/functions.html#infix-notation I wonder would that be too much for D, it already has too many features...
Apr 01 2025
On Tuesday, 1 April 2025 at 08:49:17 UTC, Dejan Lekic wrote:On Friday, 28 March 2025 at 19:47:11 UTC, Paul Backus wrote:That particular thing should be an operator. The general function-as-an-infix operator thing possibly complicates the parser a lot. It’s a completely different idea that definitely requires a DIP.Personally I would much, much rather have custom "operators" written using letters and words, which I can easily read and search for, than with symbols and punctuation marks.100% I dream of having something like this: https://kotlinlang.org/docs/functions.html#infix-notation I wonder would that be too much for D, it already has too many features...
Apr 14 2025
On Friday, 28 March 2025 at 17:06:56 UTC, Paul Backus wrote:On Thursday, 27 March 2025 at 00:26:27 UTC, Andrey Zherikov wrote:That `orElse` cannot preserve value categories. Adding `auto ref` to ´lazy T b` isn’t something the language supports. I’m not sure why, maybe it’s merely an oversight, maybe it’s because it’s complicated. ```d auto ref orElse(T, DG)(auto ref T a, DG b) { return a ? a : b(); } void test() { int x; int y; x.orElse(auto ref () => y) = 10; assert(y == 10); x = 1; x.orElse(auto ref () => y) = 11; assert(x == 11 && y == 10); } ``` It works, but it’s not really great.See [wiki](https://en.wikipedia.org/wiki/Elvis_operator) for details. Proposed syntax: ```d A ?: B ``` This is equivalent to: ```d auto R = A; // temporary (hidden) variable (cast(bool) R) ? R : B; ``` Semantics: return `A` if it's truthy, or `B` otherwise. Benefit: avoids evaluating if `A` twice which might be a call to some function with side effects.Library version: ```d auto orElse(T)(T a, lazy T b) { return a ? a : b; } unittest { string s1 = "hello"; string s2 = null; assert(s1.orElse("goodbye") == "hello"); assert(s2.orElse("goodbye") == "goodbye"); } ```
Apr 14 2025
On Thursday, 27 March 2025 at 00:26:27 UTC, Andrey Zherikov wrote:See [wiki](https://en.wikipedia.org/wiki/Elvis_operator) for details. Proposed syntax: ```d A ?: B ``` This is equivalent to: ```d auto R = A; // temporary (hidden) variable (cast(bool) R) ? R : B; ``` Semantics: return `A` if it's truthy, or `B` otherwise. Benefit: avoids evaluating if `A` twice which might be a call to some function with side effects.The lowering is actually tricky because the right-hand side ought to be evaluated only if the left-hand side is `false` as a condition. Proposing a lowering of an expression to a statement is making things difficult. The best lowering I could come up with is: ```d lhs ?: rhs // to (auto ref (auto ref __lhs) => __lhs ? __lhs : rhs)(lhs) ``` The right-hand side can be placed in the lambda as-is because it only occurs once and in fact has to be put there because passing it as a parameter evaluates it prematurely. The left-hand side *must* be evaluated first. The `auto ref` is needed to enable `(l ?: r) = x`. It would be surprising if that didn’t work if both `l` and `r` are rvalues since `(l ? l : r) = x` does work. Lastly, the `cast(bool)` is incorrect: An explicit cast to bool triggers `opCast` if present, which is something you don’t want in general, e.g. when you have a class with `opCast` and an object `c`, then `if (c)` performs a nullity check, whereas `if (cast(bool) c)` lowers to `if (c.opCast!bool)` and that does whatever it does, but certainly doesn’t check for null, but assumes it’s not null. Bottom line is, such a trivial lowering is an enhancement issue, but needs no DIP. There are virtually no surprises to be expected, no weird issues, and that is obvious; it’s just a matter of opinion if the addition provides enough value to the language and maybe its syntax (because `??` is a contender). That discussion is simply too minor to warrant a DIP. Given how many languages with similar syntax have it, it’s likely the assessment is that it does provide enough value.
Apr 14 2025









Dukc <ajieskola gmail.com> 