Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 25, 2018 Null-Coalescing Operator and Extensions | ||||
---|---|---|---|---|
| ||||
Hi, 1) I program in C# and I'm wondering if there is something like ?? (Null-Coalescing Operator) in D? (I remember some proposals in the past). 2) Is possible to create Extensions like in C#? For example: public int StrToInt (this string s){ return int.Parse(s); } var i = "123456".StrToInt(); Thanks. |
August 25, 2018 Re: Null-Coalescing Operator and Extensions | ||||
---|---|---|---|---|
| ||||
Posted in reply to SG | On Saturday, 25 August 2018 at 13:33:58 UTC, SG wrote:
> Hi,
>
> 1) I program in C# and I'm wondering if there is something like ?? (Null-Coalescing Operator) in D? (I remember some proposals in the past).
>
>
> 2) Is possible to create Extensions like in C#?
>
> For example:
>
> public int StrToInt (this string s){
> return int.Parse(s);
> }
>
> var i = "123456".StrToInt();
>
> Thanks.
1) no
2) Yes, through UFCS (Uniform Function Call Syntax). It doesn't require any special syntax, for example:
int squared(int i)
{
return i * i;
}
void main()
{
writeln(16.squared);
}
will print 256
|
August 25, 2018 Re: Null-Coalescing Operator and Extensions | ||||
---|---|---|---|---|
| ||||
Posted in reply to JN | On Saturday, 25 August 2018 at 13:42:30 UTC, JN wrote:
> 2) Yes, through UFCS (Uniform Function Call Syntax). It doesn't require any special syntax, for example:
Very simple indeed.
Thanks.
|
August 25, 2018 Re: Null-Coalescing Operator and Extensions | ||||
---|---|---|---|---|
| ||||
Posted in reply to SG | On 2018-08-25 15:33, SG wrote: > Hi, > > 1) I program in C# and I'm wondering if there is something like ?? (Null-Coalescing Operator) in D? (I remember some proposals in the past). Not in the language but it can be implemented as a library function by overloading "opDispatch". See [1] for an example. [1] https://github.com/jacob-carlborg/dlp/blob/9d524e282803070022848c01cf6cd25a61025004/source/dlp/core/optional.d#L228-L238 -- /Jacob Carlborg |
August 27, 2018 Re: Null-Coalescing Operator and Extensions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Saturday, 25 August 2018 at 19:16:26 UTC, Jacob Carlborg wrote:
> On 2018-08-25 15:33, SG wrote:
>> Hi,
>>
>> 1) I program in C# and I'm wondering if there is something like ?? (Null-Coalescing Operator) in D? (I remember some proposals in the past).
>
> Not in the language but it can be implemented as a library function by overloading "opDispatch". See [1] for an example.
>
> [1] https://github.com/jacob-carlborg/dlp/blob/9d524e282803070022848c01cf6cd25a61025004/source/dlp/core/optional.d#L228-L238
That's the null propagation operator (?.). What SG asked for is the null-coalescing operator (??). Of course, this can also be implemented in D (albeit with a slight more horrible syntax):
struct NullCoalesce {
static auto opBinaryRight(string op : "|", T)(T lhs) {
return NullCoalesceImpl!T(lhs);
}
}
alias NullCoalesce _;
struct NullCoalesceImpl(T) {
T value;
auto opBinary(string op = "|", R)(lazy R rhs) {
if (value is null) return rhs;
return value;
}
}
unittest {
int* a = null;
int b = 3;
assert(*(a |_| &b) == 3);
}
--
Simen
|
August 27, 2018 Re: Null-Coalescing Operator and Extensions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Saturday, 25 August 2018 at 19:16:26 UTC, Jacob Carlborg wrote: > On 2018-08-25 15:33, SG wrote: >> Hi, >> >> 1) I program in C# and I'm wondering if there is something like ?? (Null-Coalescing Operator) in D? (I remember some proposals in the past). > > Not in the language but it can be implemented as a library function by overloading "opDispatch". See [1] for an example. > > [1] https://github.com/jacob-carlborg/dlp/blob/9d524e282803070022848c01cf6cd25a61025004/source/dlp/core/optional.d#L228-L238 In the same vain there's "safeAccess" in my user library, see https://github.com/BBasile/iz/blob/master/import/iz/sugar.d#L1658. It's more or less the same specific D pattern (opDispatch), although the OP asked for "??" and not for "?.", which is strange. I find that the later misses more as a builtin operator. |
August 27, 2018 Re: Null-Coalescing Operator and Extensions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | On Monday, 27 August 2018 at 07:59:17 UTC, Simen Kjærås wrote:
> That's the null propagation operator (?.). What SG asked for is the null-coalescing operator (??). Of course, this can also be implemented in D (albeit with a slight more horrible syntax):
Exactly, and I know it is an example, but it doesn't work for Variant.
I was trying something like below, I need to find a way to test for all Nullable types out there, right now only works for Nullable!int.
import std.stdio, std.typecons, std.variant, std.conv;
void foo(T, U...)(T t, U u) if (is(T == Nullable!U) ) {
if(t.isNull){
writeln(u);
return;
}
writeln(t);
}
void foo(T, U...)(T t, U u) if (!is(T == Nullable!U) ){
if(t == null){
writeln(u);
return;
}
writeln(t);
}
class C {
Nullable!int m;
}
void main(){
Nullable!int i;
auto j = null;
string k = null;
Variant l = null;
C c = new C();
writefln("%s", i.isNull);
writefln("%s", j == null);
writefln("%s", k == null);
writefln("%s", l == null);
writefln("%s", c.m.isNull);
i.foo(1);
j.foo(2);
k.foo(3);
l.foo(4.3);
c.m.foo(5);
}
|
August 28, 2018 Re: Null-Coalescing Operator and Extensions | ||||
---|---|---|---|---|
| ||||
Posted in reply to SG | On Monday, 27 August 2018 at 14:59:20 UTC, SG wrote:
> On Monday, 27 August 2018 at 07:59:17 UTC, Simen Kjærås wrote:
>> That's the null propagation operator (?.). What SG asked for is the null-coalescing operator (??). Of course, this can also be implemented in D (albeit with a slight more horrible syntax):"
IMO not to have the Elvis operator in D (actually "??" is less interesting than the Elvis "?:" because of D automatic dereference and also because of boolean eval of stuff like integers and classes instances or pointer) is not a huge issue.
Not to have the safe access operator is more a problem. One is about having shorter ternary expressions (Elvis), the other is about saving sometimes 4 or 5 "&&" with at new "&&" a longer unary (Safe access).
|
August 28, 2018 Re: Null-Coalescing Operator and Extensions | ||||
---|---|---|---|---|
| ||||
Posted in reply to SG | On Saturday, 25 August 2018 at 13:33:58 UTC, SG wrote: > 1) I program in C# and I'm wondering if there is something like ?? (Null-Coalescing Operator) in D? (I remember some proposals in the past). Another example: https://github.com/aliak00/optional/blob/master/source/optional/optional.d#L340 |
August 28, 2018 Re: Null-Coalescing Operator and Extensions | ||||
---|---|---|---|---|
| ||||
Posted in reply to SG | On Monday, 27 August 2018 at 14:59:20 UTC, SG wrote: > On Monday, 27 August 2018 at 07:59:17 UTC, Simen Kjærås wrote: >> That's the null propagation operator (?.). What SG asked for is the null-coalescing operator (??). Of course, this can also be implemented in D (albeit with a slight more horrible syntax): > > Exactly, and I know it is an example, but it doesn't work for Variant. > > I was trying something like below, I need to find a way to test for all Nullable types out there, right now only works for Nullable!int. Sadly, Variant's operator overloading is problematic - there seems to be no way to write a struct such that its operator overloading is preferred over Variant's, and Variant's fails to compile. (issue 19200: https://issues.dlang.org/show_bug.cgi?id=19200) Once that issue has been fixed, this should work: // Support aliak's optional, if available: static if (__traits(compiles, {import optional;})) import optional; struct NullCoalesce { static auto opBinaryRight(string op : "|", T)(T lhs) { return NullCoalesceImpl!T(lhs); } } struct NullCoalesceImpl(T) { T value; auto opBinary(string op : "|", R)(lazy R rhs) { static if (is(typeof(value.peek!R))) { if (auto tmp = value.peek!R) return *tmp; } else static if (is(typeof(value.isNull))) { if (!value.isNull) return value.get; } else static if (is(typeof(value.unwrap))) { if (auto tmp = value.unwrap) return *tmp; } else static if (is(typeof(value == null))) { if (value != null) return value; } else { static assert(false, "Cannot perform null-coalescing on non-nullable type "~T.stringof~"."); } return rhs; } } alias NullCoalesce _; unittest { import std.variant; import std.typecons; int* a = null; auto b = new int; assert((a |_| b) == b); a = new int; assert((a |_| b) == a); Variant c; assert((c |_| 3) == 3); c = 4; assert((c |_| 3) == 4); Nullable!int d; assert((d |_| 3) == 3); d = 4; assert((d |_| 3) == 4); static if (is(typeof(Optional!int))) { Optional!int e; assert((e |_| 3) == 3); e = 4; assert((e |_| 3) == 4); } } Now, as has been pointed out, that only work for null-coalescing, not null-propagation. It seems writers of Optional, Variant, SumType, and so on, have decided not to support this out of the box, but rather wrap it separately, like Basile B.'s SafeAccess[1] and aliak's dispatch[2]. There's no real obstacle to wrapping member access directly in Optional!T such that it always return a Optional!(typeof(member)), though. I've written an Optional somewhere that does safe access out of the box, but it seems to be on my work computer, not this one. -- Simen [1]: https://github.com/BBasile/iz/blob/master/import/iz/sugar.d#L1658 [2]: https://code.dlang.org/packages/optional |
Copyright © 1999-2021 by the D Language Foundation