Re: Null-Coalescing Operator and Extensions

2018-08-28 Thread aliak via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 13:27:28 UTC, Simen Kjærås wrote:
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 been back and forth on this many times with an Optional 
type. I've come to the conclusion that providing a "safe" 
opDispatch in the optional type itself is worth if it the 
Optional type does not have any member functions. Otherwise it'll 
essentially cripple the user type if it has functions named the 
same. And since the optional types (presented around the forums) 
seem to support range access, it basically means you can't have 
an Optional!Range type - or any T that has a member called empty 
(which is not uncommon IMO). I can't figure out a way around this 
:(


Cheers,
- Ali


Re: Null-Coalescing Operator and Extensions

2018-08-28 Thread Simen Kjærås via Digitalmars-d-learn

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


Re: Null-Coalescing Operator and Extensions

2018-08-28 Thread Kagamin via Digitalmars-d-learn

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


Re: Null-Coalescing Operator and Extensions

2018-08-27 Thread Basile B. via Digitalmars-d-learn

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).


Re: Null-Coalescing Operator and Extensions

2018-08-27 Thread SG via Digitalmars-d-learn

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);
}


Re: Null-Coalescing Operator and Extensions

2018-08-27 Thread Basile B. via Digitalmars-d-learn

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.


Re: Null-Coalescing Operator and Extensions

2018-08-27 Thread Simen Kjærås via Digitalmars-d-learn

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


Re: Null-Coalescing Operator and Extensions

2018-08-25 Thread Jacob Carlborg via Digitalmars-d-learn

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


Re: Null-Coalescing Operator and Extensions

2018-08-25 Thread SG via Digitalmars-d-learn

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.


Re: Null-Coalescing Operator and Extensions

2018-08-25 Thread JN via Digitalmars-d-learn

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


Null-Coalescing Operator and Extensions

2018-08-25 Thread SG via Digitalmars-d-learn

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.