
Maybe Not [video] - kgwxd
https://www.youtube.com/watch?v=YR5WdGrpoug
======
anon1253
I really like this idea of composing selectable attributes as schemas (ala
RDF). I've been fairly reluctant in adopting specs into my own code, mostly
because in a lot of cases I just didn't see the benefit (not for the things I
typically do, not saying I wasn't interested in generative testing and the
likes ... those still seem very promising but also hard to get right).
Especially, when dealing with "distributed" things (like the world wide web,
where everything is maybe and only some things useful). And, RDF got this
surprisingly right. I was sort-of half expecting him to also introduce PROLOG
into it, but maybe next time. The idea of collections of subject-predicate-
object statements forming an isomorphism with graphs, and sets of these
statements form concrete "aggregates" plays extremely well with the idea of
unification through search.

Somewhat tangentially, it also keeps reminding me somehow of Alfred North
Whitehead's concepts of reality as process flows
[https://en.wikipedia.org/wiki/Alfred_North_Whitehead#Whitehe...](https://en.wikipedia.org/wiki/Alfred_North_Whitehead#Whitehead's_conception_of_reality)

"In summary, Whitehead rejects the idea of separate and unchanging bits of
matter as the most basic building blocks of reality, in favor of the idea of
reality as interrelated events in process. He conceives of reality as composed
of processes of dynamic "becoming" rather than static "being", emphasizing
that all physical things change and evolve, and that changeless "essences"
such as matter are mere abstractions from the interrelated events that are the
final real things that make up the world."

~~~
ISO-morphism
Here's Rich Hickey giving a talk in 2009 guided by Whitehead quotes [1]

[1] [https://www.infoq.com/presentations/Are-We-There-Yet-Rich-
Hi...](https://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey)

------
dwohnitmok
Hickey's `Maybe` example feels misguided (about breaking existing callers). If
Maybe is an input just keep the original function around and provide a new one
that wraps it.

    
    
        originalF :: x -> y
    
        f :: Maybe x -> y
        f None = newDefaultBehavior
        f (Some x) = originalF x
    

If `Maybe` is an output then existing callers SHOULD be broken, because they
must now handle a new possibility of failure they didn't before. The fact that
this doesn't happen in Clojure is actually a source of pain for me.

It's also rather interesting that Hickey also comes to the same conclusion
that optionality doesn't belong in a data structure, but for slightly
different reasons:
[https://news.ycombinator.com/item?id=17906171](https://news.ycombinator.com/item?id=17906171)

~~~
yen223
If x represented a set with some values

    
    
      x = {RED, GREEN, BLUE}
    

It would be really swell if the optional type `Maybe x` were a strict
superset:

    
    
      Maybe x = {RED, GREEN, BLUE, None}
    

This means functions that map `Maybe x -> y` can accept values of type `x`
without issue.

But in Haskell (and OCaml) it's not. What we actually have is something more
like

    
    
      Maybe x = {Some(RED), Some(GREEN), Some(BLUE), None}
    

which is a totally different set from `x`, which is why functions which
shouldn't break, ultimately do.

~~~
tel
The downside of that (which can be provided by union types) is that `Maybe
(Maybe X) == Maybe X` which may or may not be what you're after. The
particular weakness is the interplay with generics where `forall t. Maybe t`
depends upon the `Maybe` and the `t` not interacting. If you've got `forall t.
t | null` then this type may secretly be the same as `t`---and if you handle
nulls then it might conflate meanings unintentionally.

~~~
ndh2
So you're saying that the one Nothing has a different meaning than the other
Nothing, and that this is something that anybody would want? Or that we have a
Nothing and a Just Nothing? I'm sorry, but I don't get how that would be
considered good design in any context. Do you have any example where this
would be considered sensible?

~~~
tel
I am.

In any concrete context, Maybe (Maybe A) could _probably_ be simplified to
just Maybe A as we expect. Alternatively, we could be in a situation where
there are two notions of failure (represented here as Nothing and Just
Nothing) in which case we'd be better off simplifying to Either Error A where
Error covers you multiplicity of error cases.

But while these are all obvious in a concrete context, what we often are doing
is instead compositional. If I want to write code which works over (Maybe a)
for some unknown, library-user-declared type `a` then I may very well end up
with a Maybe (Maybe Int) that I can't (and mustn't) collapse.

As a concrete example, consider the type of, say, a JSON parser

    
    
        ParserOf a = Json -> Maybe a
    

We hold the notion of failure internal to this type so that we can write

    
    
        fallback : ParserOf a -> ParserOf a -> ParserOf a
    

which tries the first parser and falls back to the second if the first results
in error. We might also want to capture these errors "in user land" with a
combinator like

    
    
        catch : Parser a -> Parser (Maybe a)
    

If we unwrap the return type of `catch` we get a Maybe (Maybe a) out of a
compositional context (we can't collapse it). Additionally, the two forms of
failure are distinct: one is a "handled" failure and the other is an unhandled
failure.

~~~
JadeNB
> In any concrete context, Maybe (Maybe A) could _probably_ be simplified to
> just Maybe A as we expect.

And doing so is just what `join :: m ( m a ) -> m a` specialises to for `m =
Maybe`!

~~~
tel
That's just one way to do it. Another might be

    
    
        collect :: Maybe (Maybe a) -> Either[Bool, a]

~~~
JadeNB
But you mentioned simplifying `Maybe (Maybe a)` to `Maybe a`, which your
`collect` doesn't do (at least not directly).

(Also, shouldn't `Either[Bool, a]` (which I don't know how to make sense of)
be `Either Bool a`? Even with this signature, I'm not sure what the
implementation would be, and Hoogle doesn't turn up any obviously correct
results (
[https://www.haskell.org/hoogle/?hoogle=collect](https://www.haskell.org/hoogle/?hoogle=collect)
[https://www.haskell.org/hoogle/?hoogle=Maybe+%28Maybe+a%29+-...](https://www.haskell.org/hoogle/?hoogle=Maybe+%28Maybe+a%29+-%3E+Either+Bool+a)
), but that's probably my fault.)

~~~
dllthomas
I think the obvious implementation is `maybe (Left False) (maybe (Left True)
Right)`

If we have a value then we clearly have both layers. If we don't have a value
then we need to distinguish Nothing from Just Nothing by way of the book.

~~~
JadeNB
Oh, I see; we're thinking of `Maybe a` as `a + ()`, and then identifying `(a +
()) + ()` with `a + (() + ())` and then `() + ()` with `Bool`. Thanks!

~~~
dllthomas
Right, exactly!

------
Avi-D-coder
Could the title be changed to include "\- Rich Hickey". I know I am certainly
more likely to click the link when it's one of his talks.

~~~
kgwxd
It did originaly. It is the full title and, without it, it's very vague. Maybe
if I had remembered to put [video] in there, the mods wouldn't have touched
it. Or maybe not.

~~~
oneeyedpigeon
It's pretty meaningless currently ("Maybe Not [video]"). It would be nice to
know, at the very least, that it's a video of a _talk_ , but info. about the
actual content of the talk would be preferable.

------
openfuture
Great talk, really excited to see how he is going to solve imports and
reification for Clojure [so far only rust and haskell have this figured out].

I'm just so glad that Clojure exists, it is doing all the good design things
to make programming pleasant but it has a different approach from the usual
suspects which is incredibly valuable!

Being dynamic and interactive is great for UI/UX design since that,
especially, benefits from the tight feedback loop and I'm becoming more and
more bullish on making the type system separate like this and thinking of it
as synonymous with tests, it makes a lot of sense (separation of concerns...)

Also coming from mathematics I can see a analogy to the preference of working
in open sets (so that you can always take a point arbitrarily close to the
edge and still make an open neighborhood around it) and what he is calling an
open system. This preference for open sets over dense ones seems
counterintuitive at first sight but is the basis on which analysis is built.
Type systems feel a bit 'dense' in the sense that they force you to write
programs that are overspecified?

Anyway I just look forward to seeing experience accumulate with these
different technologies so that we may learn more about how we ought to design
systems !

------
boogiewoogie
"I got six maybe sheep in my truck."

------
logistark
I have this strange feeling, that first half-hour was totally unnecesary for
what the sencond half is. I mean, that it feels that he have to rant always
about. Like ok, this ideas are wrong, this is my idea that is totally new(not
really) and is the right thing to do. Nowadays, that ranting about Java is not
so cool, he have to rant about types. Only to finish saying that he is going
to add to Spec something that have already been implemented in Clojure
[https://github.com/plumatic/schema](https://github.com/plumatic/schema). So
at the end of the talk, what's the point?

------
boogiewoogie
Punchline of the talk starts at 38:00

------
karmakaze
I'm really excited about the way this is progressing. As a way to think of it
(and not demote it in any way) is that it's like PropTypes with React done
with reusability and less verbosity. The reference to GraphQL really makes it
clear that we want deep separated specification.

------
chubot
Great talk! I’ve watched a lot of Hickey’s talks over the years, and thought
he might have "run out of steam" by now. But there are some new insights here
that I enjoyed.

One of his main points is that Maybe is context-dependent, and other aspects
of schemas are as well. This is a great and underappreciated point.

It’s related to a subtle but important point that Google learned the hard way
over many years with respect to protocol buffers. There’s an internal wiki
page that says it better, but this argument has spilled out on to the
Internet:

[https://stackoverflow.com/questions/31801257/why-required-
an...](https://stackoverflow.com/questions/31801257/why-required-and-optional-
is-removed-in-protocol-buffers-3)

In proto3, they removed the ability to specify whether a field is optional.
People say that the reason is “backward compatibility”, which is true, but I
think Hickey’s analysis actually gets to the core of the issue.

The issue is that the shape/schema of data is an idea that can be reused
across multiple contexts, while optional/required is context-specific. They
are two separate things conflated by type systems when you use constructs like
Maybe.

When you are threading protocol buffers through long chains of servers written
and deployed at different times (and there are many of these core distributed
types at Google), then you'll start to appreciate why this is an important
issue.

(copy of lobste.rs comment)

