November 06, 2017
On Monday, 6 November 2017 at 10:12:11 UTC, Jonathan M Davis wrote:
> All it does is take the expression
>
> x ? x : y
>
> and make it
>
> x ?: y

Yes, that is an issue because it means that typos no longer are caught. E.g. if you accidentally comment out or delete the second expression.

Which is why I think ?? or some other choice would offer better usability.

> The difference is that you think that the feature is worth the cost, not that the folks who don't want to use the feature don't have to pay the cost.

Indeed.

November 06, 2017
On 10/28/17 04:38, Andrei Alexandrescu wrote:
> Walter and I decided to kick-off project Elvis for adding the homonym
> operator to D.
>
> Razvan Nitu has already done a good part of the work:
>
> https://github.com/dlang/dmd/pull/7242
> https://github.com/dlang/dlang.org/pull/1917
> https://github.com/dlang/dlang.org/pull/1918
>
> What's needed is a precise DIP that motivates the feature properly and
> provides a good proposal for it. I'm no fan of bureaucracy but we really
> need to be pedantic about introducing language features. Walter argued
> thusly in a PR, and I agree:
>
> "I'm concerned that the elvis operator is not well understood, and we
> shouldn't be designing it in the comments section here. A DIP needs to
> be written. Things like operator precedence, side effects, type
> resolution, comparison with the operator in other languages, grammar
> changes, lvalues, how it would appear in the generated .di file if it
> isn't its own operator, etc., should be addressed."
>
> A lowering looks like the straightforward approach, of the kind:
>
> expr1 ?: expr2
>
> ==>
>
> (x => x ? x : expr2)(expr1)
>
> Who wants to join Razvan in Project Elvis?
>
>
> Thanks,
>
> Andrei


C# has extensive experience with this operator and I think it would be wise to study the history of what they did and why the did it. NOTE: I understand that other languages have it, and there are variations on the theme, but C# has many similarities to D and extensive "in practice" idioms.

C# got the Elvis operator before it got the Null Conditional operator. In C# it only covers the case: a == null. The reason is that in practice most devs only use it like so: a != null ? a : b.

The funny thing is that it was almost never used.

Some years later the C# team introduces the Null-Conditional operator: ?. which allows you to write: obj1?.obj2?.prop3 ?? constant.

NOW people start using Null Coalescing all over the place.

I am all for the Elvis operator, however I have two reservations about it. The first is that I don't see much use for it without a null-conditional. The second is that the current proposed syntax ?: is MUCH to easily confused with ?.

This is not easy to read: obj1?.obj2?.prop3?:constant.

When designing syntax sugar, ergonomics are very important, otherwise people won't use it. Microsoft spent a LOT of time and treasure to learn these lessons for us. I see no reason to ignore them just because "we don't like Microsoft"

My proposal would be to copy what MSFT did, expect that I would I would introduce both operators at the same time.

Syntax as follows: obj1?.obj2?.prop3 ?? constant

In practice I don't see much use of the idiom outside of null's. The ONLY other thing that would work there is a boolean field and you might as well just return the boolean itself because the return values have to match types.

For example:
return obj1.bool ?? obj2 //Error: incorrect return type
return obj1 ?? obj2 // Pass: if same type

I cannot actually imagine a scenario outside of objects (including strings) where you could actually use it since the left-hand side MUST evaluate to a boolean.

Also, I am going to start repeating this mantra: Just because something CAN be done in the library, does not mean it SHOULD be done in the library.

Ergonomics matters. Yes, I understand that D is a powerful language, but Syntax Sugar has it's place in taking common idioms and standardizing them in the language itself (English is loaded with stuff like that) so that everyone can "speak the same language".

-- 
Adam Wilson
IRC: LightBender
import quiet.dlang.dev;
November 06, 2017
On Monday, 6 November 2017 at 19:13:59 UTC, Adam Wilson wrote:
> On 10/28/17 04:38, Andrei Alexandrescu wrote:
>> Walter and I decided to kick-off project Elvis for adding the homonym
>> operator to D.
>>
>> Razvan Nitu has already done a good part of the work:
>>
>> https://github.com/dlang/dmd/pull/7242
>> https://github.com/dlang/dlang.org/pull/1917
>> https://github.com/dlang/dlang.org/pull/1918
>
> Some years later the C# team introduces the Null-Conditional operator: ?. which allows you to write: obj1?.obj2?.prop3 ?? constant.
>
> NOW people start using Null Coalescing all over the place.
>

So C# embraced the Null. Everything is nullable and you are expected to ?. proof it if you don’t know in advance.

In contrast other languages (e.g. Scala) decided to discourage the use of null in favor of algebraic type Option!T and even remove the null all together.

> I am all for the Elvis operator, however I have two reservations about it.

To me the biggest reservation is “embracing the null” that this entails.

In other words since we dedicate a feature to support nulls that indicates null return is an endorsed aproach to e.g. model APIs and libraries that deal with optional values.

I’d argue this NOT what we want. Nullability is best captured in the typesystem even if in the form of Nullable!T.


November 06, 2017
On 2017-11-06 20:40, Dmitry Olshansky wrote:

> I’d argue this NOT what we want. Nullability is best captured in the typesystem even if in the form of Nullable!T.

Yeah, it would be better if the elvis operator good integrate with a nullable/option type as well in addition to null.

-- 
/Jacob Carlborg
November 06, 2017
On Monday, 6 November 2017 at 19:55:13 UTC, Jacob Carlborg wrote:
> On 2017-11-06 20:40, Dmitry Olshansky wrote:
>
>> I’d argue this NOT what we want. Nullability is best captured in the typesystem even if in the form of Nullable!T.
>
> Yeah, it would be better if the elvis operator good integrate with a nullable/option type as well in addition to null.

What's the point when we can already do it easily in a library, and arguably with better ergonomics? (http://forum.dlang.org/post/fshlmahxfaeqtwjbjouz@forum.dlang.org)

auto tree = new Node(1,
	               new Node(2),
	               new Node(3,
	                   null,
	                   new Node(4)
	               )
	           );

import std.stdio;
writeln(safeDeref(tree).right.right.val.orElse(-1));
writeln(safeDeref(tree).left.right.left.right.orElse(null));
writeln(safeDeref(tree).left.right.left.right.val.orElse(-1));

vs.

writeln(tree?. right?.right?.val ?: -1);
writeln(tree?.left?.right?.left?.right);
writeln(tree?.left?.right?.left?.right?.val ?: -1);

The functionality is probably a good idea, but a library solution is doable today without any acrobatics.
November 06, 2017
I can't quite see why this proposal is such a big deal to people - as has been restated, it's just a quick change in the parser for a slight contraction in the code, and nothing language-breaking, it's not a big change to the language at all.

On Monday, 6 November 2017 at 19:13:59 UTC, Adam Wilson wrote:
> I am all for the Elvis operator, however I have two reservations about it. The first is that I don't see much use for it without a null-conditional. The second is that the current proposed syntax ?: is MUCH to easily confused with ?.
>
> This is not easy to read: obj1?.obj2?.prop3?:constant.
>
> When designing syntax sugar, ergonomics are very important, otherwise people won't use it. Microsoft spent a LOT of time and treasure to learn these lessons for us. I see no reason to ignore them just because "we don't like Microsoft"
>
> My proposal would be to copy what MSFT did, expect that I would I would introduce both operators at the same time.
>
> Syntax as follows: obj1?.obj2?.prop3 ?? constant
>
> In practice I don't see much use of the idiom outside of null's. The ONLY other thing that would work there is a boolean field and you might as well just return the boolean itself because the return values have to match types.

I feel this is kind of embellished somewhat. When you write

> This is not easy to read: obj1?.obj2?.prop3?:constant.

you're not separating it out as you do when you write your preferred version:

> Syntax as follows: obj1?.obj2?.prop3 ?? constant

How is

> obj1?.obj2?.prop3 ?: constant

not as easy to read as


> obj1?.obj2?.prop3 ?? constant

to me they are the same in terms of readability, only with ?? you have greater chances of mistyping and adding a second ? in there somewhere, whereas the ?: is just a contraction of the current syntax, I really don't think it's that difficult, so I'm not sure what people's hang-ups are, but I don't think the argument that ?? is easier to read than ?: holds any weight here, because one *is* a change to the language, and the other is a change to the parser and a contraction of a standard convention.


November 07, 2017
On Monday, 6 November 2017 at 19:13:59 UTC, Adam Wilson wrote:
> On 10/28/17 04:38, Andrei Alexandrescu wrote:
>> [...]
>
>
> C# has extensive experience with this operator and I think it would be wise to study the history of what they did and why the did it. NOTE: I understand that other languages have it, and there are variations on the theme, but C# has many similarities to D and extensive "in practice" idioms.
>
> [...]

I strongly agree with you.
November 07, 2017
On Tuesday, 7 November 2017 at 09:42:50 UTC, Satoshi wrote:
>
> I strongly agree with you.

As I wrote earlier int this thread. Kotlin has the `?.` operator for the same reason. I honestly can't think of a more obvious operator for that purpose...
November 07, 2017
On Monday, 6 November 2017 at 19:13:59 UTC, Adam Wilson wrote:
> On 10/28/17 04:38, Andrei Alexandrescu wrote:
>> [...]
>
>
> C# has extensive experience with this operator and I think it would be wise to study the history of what they did and why the did it. NOTE: I understand that other languages have it, and there are variations on the theme, but C# has many similarities to D and extensive "in practice" idioms.
>
> [...]

My problem with a null coalescing operator is that it bakes in one particular monad into the syntax, and it's not even a monad that's that useful for most idiomatic D code I've seen or written. I'd rather have do notation or something like that.

Atila
November 07, 2017
On Monday, 6 November 2017 at 20:14:17 UTC, Meta wrote:
> [...]
> import std.stdio;
> writeln(safeDeref(tree).right.right.val.orElse(-1));
> writeln(safeDeref(tree).left.right.left.right.orElse(null));
> writeln(safeDeref(tree).left.right.left.right.val.orElse(-1));
>
> vs.
>
> writeln(tree?. right?.right?.val ?: -1);
> writeln(tree?.left?.right?.left?.right);
> writeln(tree?.left?.right?.left?.right?.val ?: -1);
>
> The functionality is probably a good idea, but a library solution is doable today without any acrobatics.

Show me a library solution that works fine with IDE completion (so for the safe navigation operator, not the Elvis one).