Boost logo

Boost :

Subject: Re: [boost] [GSoC] [Boost.Hana] Formal review request
From: pfultz2 (pfultz2_at_[hidden])
Date: 2014-08-01 15:21:36


> If the methods are separated from the type classes, they can't have a
default
> definition which depends on the MCD that's used. For example, let's
> pretend I
> have two MCDs for Foldable; `fold_mcd` and `unpack_mcd`. `fold_mcd`
> requires
> both `foldl` and `foldr`, and `unpack_mcd` requires `unpack`. Now, there
> are
> multiple ways to implement `sum`. Two of them are:
>
> auto sum = [](auto xs) {
> return foldl(_+_, int_<0>, xs);
> };
>
> auto sum = [](auto xs) {
> return unpack(some_very_fast_sum_on_variadic_packs, xs);
> };
>
> where `some_very_fast_sum_on_variadic_packs` would put the `xs` in an
> array
> and then return a `int_<sum_of_the_array>`. However, in `fold_mcd`,
> `unpack`
> is implemented inefficiently, and in `unpack_mcd`, `fold` is decent but it
> is still likely not as efficient as a user-provided one. Which
> implementation
> for `sum` do I choose? If I pick the first one, it's going to be
> suboptimal
> with objects that used `unpack_mcd`. If I pick the second one, it's going
> to
> be suboptimal with objects that used `fold_mcd`.

But as user if I was defining my own `sum` function, how would I do it? I
can't change the typeclass, since it is in another library. Is there a way
for
me as an user to optimize my sum function based on which MCD was
implemented?
And if so, couldn't the library do the same?

> If you go look at the Foldable type class in Haskell, you'll see that
> there
> are a bunch of related functions provided with the type class, yet they
> are
> not included in it. My opinion is that they might just as well be included
> in the type class, as you could then redefine them for improved
> performance.
> I just searched online for a rationale or at least some insight about this
> decision, but I did not find anything.

I think the rational is similar to the rational for using non-member
functions. One reason is consistency. People are going to add new
algorithms,
but they won't be added to the typeclass. Futhermore, if they want to allow
overloading the algorithm for optimization, they will create new
typeclasses.
So now you have two different ways to accomplish the same thing. Another
reason, is it will make the typeclass simpler and improve encapsulation. A
typeclass is defined by the minimum necessary and not by another 50
algorithms.

> That being said, Monads are a common hurdle for people learning FP (I
> myself
> am super new to this stuff, BTW) and I'm not sure changing the name would
> do
> any good. To grok Monads, you have to bang your head a bit, not think of
> them
> as one particular metaphor[1]. Also, FWIW, I think that defining Monads
> with
> `join` (as in Hana) instead of `bind` (as in Haskell) makes them easier to
> understand, but that's just me.

I do agree that `join` is easier than `bind`.

> Yup, you're missing `cons` and `nil`. But you're right that `List` can be
> refactored, and I plan to do it. For example, `filter` can be implemented
> if
> you give me `nil` and a `Monad`, which makes a `MonadZero` (a Monad with a
> neutral element):
>
> // pseudo code
> auto filter = [](auto pred, auto xs) {
> auto go = [=](auto x) { return pred(x) ? lift(x) : nil; };
> return join(fmap(go, xs));
> };
>
> You get `fmap` from Functor, `lift` from Applicative and `nil` from
> MonadZero.
> Then you can filter Maybes, with `nil` being `nothing`!

Awesome.

> > - It's important to note that the `decltype_` function will only work
> for
> > constexpr-friendly types.
>
> I don't get it? Can you please expand?

I should clarify that I'm referring to the use of `decltype_` within the
context of constexpr. It will work outside of that. So, for example, if I
were
to static_assert that two types were the same, as a simple example:

    template<class T>
    void foo(T x)
    {
        auto y = bar();
        static_assert(decltype_(x) == decltype_(y), "Not matching types");
    }

This won't work for if types are not a literal type nor have a constexpr
constructed. This will fail even if `decltype_` was to take the expression
by
reference. Ultimately, I believe the language should be changed to allow for
this.

--
View this message in context: http://boost.2283326.n4.nabble.com/Re-GSoC-Boost-Hana-Formal-review-request-tp4665622p4665929.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk