On 12/11/13 11:32 AM, Robert Clipsham wrote:
On Tuesday, 10 December 2013 at 23:53:25 UTC, Ary Borenszweig wrote:
On 12/10/13 5:35 PM, Namespace wrote:
I love Monadic null checking. Would be great if D would have it.
What does a monad have to do with that?
(just out of curiosity... BTW, the other day I friend tried to explain
me monads and he realized couldn't understand them himself)
Monads suffer from the same problem algebra, templates and many other
things do in that they have a scary name and are often poorly explained.
They way I like to think of monads is simply a box that performs
computations. They have two methods, bind and return. return lets you
put a value into the box, and bind lets you call some function with the
value that's in the box. Probably the simplest example is the maybe
monad ("monadic null checking"). The idea is to let you change something
like this:
----
auto a = ...;
if (a != null) {
auto b = a.foo();
if (b != null) {
b.bar();
// And so on
}
}
----
Into:
----
a.foo().bar();
----
Here, the bind and return methods might look something like:
----
// "return" function
Maybe!Foo ret(Foo f) {
return just(f);
}
auto bind(Maybe!Foo thing, Foo function(Foo) fn) {
if(thing) {
return ret(fn(thing));
}
return nothing();
}
----
There are two functions here for getting instances of maybe - nothing
and just. Nothing says "I don't have a value" and just says "I have a
value". The bind method then simply says "if I have a value, call the
function, otherwise just return nothing". The code above would be used
as follows:
----
bind(bind(a, &foo), &bar);
----
With a bit of magic you can get rid of the overhead of function pointers
and allow it to work with other function types, but it shows the general
concept - wrap up the values, then use bind to chain functions together.
The ?. operator mentioned in the article is simply some syntactic sugar
for a monad, hence "monadic null checking".
Thanks for the explanation. I think I understand monads a bit more now. :-)
However, isn't it too much to call the "?." operator "monadic null
checking"? I see it as just syntax sugar:
foo?.bar
is the same as:
(temp = foo) ? temp.bar : null
And so:
foo?.bar?.baz
it the same as:
(temp2 = ((temp = foo) ? temp.bar : null)) ? temp2.baz : null
By the way, in Crystal we currently have:
class Object
def try
yield
end
end
class Nil
def try(&block)
nil
end
end
You can use it like this:
foo.try &.bar
foo.try &.bar.try &.baz
Not the nicest thing, but it's implemented as a library solution. Then
you could have syntactic sugar for that.
Again, I don't see why this is related to monads. Maybe because monads
are boxes that can perform functions, anything which involves a
transform can be related to a monad. :-P