Jump to page: 1 2
Thread overview
Elvis operator - shortened ternary operator
Mar 28
Dukc
Mar 28
matheus.
Mar 28
Dukc
Mar 28
matheus
6 days ago
Quirin Schroll
6 days ago
Quirin Schroll
6 days ago
Quirin Schroll
March 27

See wiki for details.

Proposed syntax:

A ?: B

This is equivalent to:

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.

March 28

On Thursday, 27 March 2025 at 00:26:27 UTC, Andrey Zherikov wrote:

>

See wiki for details.

Proposed syntax:

A ?: B

This is equivalent to:

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!

A || B;
March 28
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) for

> I 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.
March 28

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!

March 28

On Friday, 28 March 2025 at 12:22:24 UTC, matheus. wrote:

>

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 for

>

I believe we already have this!

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.

Yes. The main benefit is that a is not calculated twice if it's a function like here: auto d = a() ? a() : b();

March 28

On Thursday, 27 March 2025 at 00:26:27 UTC, Andrey Zherikov wrote:

>

See wiki for details.

Proposed syntax:

A ?: B

This is equivalent to:

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:

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");
}
March 28
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.
March 28
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.
April 01
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...
6 days ago

On Thursday, 27 March 2025 at 00:26:27 UTC, Andrey Zherikov wrote:

>

See wiki for details.

Proposed syntax:

A ?: B

This is equivalent to:

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:

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.

« First   ‹ Prev
1 2