August 21, 2012
On 08/21/2012 06:30 AM, Simen Kjaeraas wrote:
> On Tue, 21 Aug 2012 13:55:58 +0200, Regan Heath <regan@netmail.co.nz>
> wrote:

>> On the other hand, the suggested syntax of
>> "bob?.department?.head?.name" from Kotlin is pure genius, and has a
>> good chance of actually being used.
>
> Absolutely. Probably hard to include in D though, as a ? .b is the
> beginning of a conditional expression.

There are many characters that has been neglected by D:

  bob⸮.department⸮.head⸮.name

:p (If not visible on your screen, that character is U+2E2E.)

Ali

August 21, 2012
> There are many characters that has been neglected by D:
>
>   bob⸮.department⸮.head⸮.name
>
> :p (If not visible on your screen, that character is U+2E2E.)
>
> Ali

Nice! No-one of the Ascii-Trapped would miss that: self documentation indeed.

August 22, 2012
On Tue, Aug 21, 2012 at 10:17 PM, Nick Treleaven <nospam@example.net> wrote:
> On 21/08/2012 14:30, Simen Kjaeraas wrote:


>> I have an Option struct on my home computer that only allows access to the held value if the error case is simultaneously handled:
>>
>> Option!int a = foo();
>>
>> int n = a.match!(
>>      (int x) => x,
>>      (None n) => 0 // or throw, or what have you.
>>      );
>>
>> The same solution is perfectly adaptable to MaybeNull, MaybeNan, and
>> probably
>> a host of others of the same family.
>>
>> With some clever use of opDispatch, one could write an Option struct that lets you call methods and acces members of the wrapped type, and return Option!ReturnType.
>
>
> Apart from the opDispatch bit, I've been slowly working on something similar
> (Boost license):
>
> https://github.com/ntrel/d-maybe/blob/master/maybe.d
>
> I'm still working on it, but the basic ideas are there. I think the best bit
> is apply(), which supports passing multiple Maybe values, calling the
> delegate only if all Maybes are valid. In fact Maybe.map() is unnecessary
> due to apply().

Then, both Simen and you could code a generic algebraic datatype generator, with the associated matching functions (and probably mapping / reducing) Here come the whole Haskell / ML menagerie of types :)

mixin(ADT("
Tree(T):
    Leaf(T)
  | Branch(Tree, Tree)
"));

or something like that... And then encode JSON like this.

Or update std.typecons.Algebraic to make it deal with recursive definitions...
August 22, 2012
On Tue, Aug 21, 2012 at 4:55 AM, Regan Heath <regan@netmail.co.nz> wrote:

> Plus, I don't buy the argument that having to explicitly type ".get" will stop anyone from automatically coding statements like:
>
> val g: Option[T] = f.doSomething()
> g.get.doSomethingElse()
>
> and suffering the exact same null pointer exception/error despite using Option and boxing into a Not-Null type.
>
>
> R
>
>
C++ and D have language constructs to allow you to cast away const-ness and immutability, does that mean we have to do away with the concept just because there is a way around it?


--
Ziad


August 22, 2012
On Wed, 22 Aug 2012 19:37:09 +0200, Ziad Hatahet <hatahet@gmail.com> wrote:

> C++ and D have language constructs to allow you to cast away const-ness and
> immutability, does that mean we have to do away with the concept just
> because there is a way around it?

No, but a cast sticks out like a sore thumb. foo.get().bar() does not.

-- 
Simen
August 22, 2012
> Time ago I have suggested a syntax like Foo@ to represent in D the subtype of Foo references that can't be null.

That would be nice. Anyhow a lot better as any library solution. But I think it will be resulting in a NotNullable struct in std.typecons...
August 23, 2012
On 21/08/2012 21:17, Nick Treleaven wrote:
>> I have an Option struct on my home computer that only allows access to
>> the held value if the error case is simultaneously handled:
>>
>> Option!int a = foo();
>>
>> int n = a.match!(
>>      (int x) => x,
>>      (None n) => 0 // or throw, or what have you.
>>      );

I've now implemented match, similar to the above:
https://github.com/ntrel/d-maybe/blob/master/maybe.d#L222

My match() always returns Maybe!T, because for pointers the lambdas could return null.

Taken from the unittest:

assert(match!(to!string, ()=>"<invalid>")(maybe(2)) == "2");
assert(match!(to!string, ()=>"<invalid>")(Maybe!int()) == "<invalid>");
assert(match!((x, y)=>text(x, y), {})(maybe(2), maybe(34)) == "234");
assert(match!((x, y)=>text(x, y), {})(Maybe!int(), maybe(34)) == null);
assert(match!((x, y)=>text(x, y), ()=>"none")(Maybe!int(), maybe(34)) == "none");

I'd be interested to see your Option code.

Nick
August 23, 2012
Is there any special reason why these functions doesn't get "Maybe" as (const) ref?

void show(T)(Maybe!T m)
bool opEquals(Maybe!T m)
void opAssign(Maybe!T m)
August 23, 2012
On Thu, 23 Aug 2012 18:27:41 +0200, Nick Treleaven <nospam@example.net> wrote:

> I'd be interested to see your Option code.

Here you go. After looking at your code, and with Modern C++ Design fresh in mind, I see that match and hasValue might have worked better as free functions.

I took the liberty of implementing the optional function calls discussed earlier. If your eyes glaze over or you feel an urge to kill, you are likely looking at that part of the code.

-- 
Simen

August 24, 2012
On 23/08/2012 18:27, Namespace wrote:
> Is there any special reason why these functions doesn't get "Maybe" as
> (const) ref?
>
> void show(T)(Maybe!T m)
> bool opEquals(Maybe!T m)
> void opAssign(Maybe!T m)

No special reason. The Maybe struct is usually pretty small so using ref didn't occur to me, but if it's good practice I should do so. I suppose ref would be necessary because T could be a struct. I hadn't thought about const at all yet.

BTW show is just a test function, I recently made it private.

Nick