Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jan 31 15:06

    ldionne on gh-pages

    Update benchmarks to 490dbf6 fo… (compare)

  • Jan 24 07:47

    ldionne on gh-pages

    Update benchmarks to 490dbf6 fo… (compare)

  • Jan 23 02:04
    pthom commented #432
  • Jan 18 12:46

    ldionne on gh-pages

    Update benchmarks to 490dbf6 fo… (compare)

  • Jan 16 22:27
    ricejasonf commented #434
  • Jan 05 06:22
    ricejasonf commented #330
  • Jan 03 11:40

    ldionne on gh-pages

    Update benchmarks to 490dbf6 fo… (compare)

  • Jan 02 00:33
    ricejasonf closed #434
  • Jan 02 00:33
    ricejasonf commented #434
  • Jan 02 00:04
    ricejasonf opened #434
  • Dec 27 2018 13:11

    ldionne on gh-pages

    Update benchmarks to 490dbf6 fo… (compare)

  • Dec 22 2018 11:56
    pthom commented #432
  • Dec 22 2018 11:55
    pthom commented #432
  • Dec 21 2018 15:48
    pthom synchronize #432
  • Dec 21 2018 09:19
    sdebionne opened #433
  • Dec 21 2018 00:08
    ricejasonf commented #432
  • Dec 21 2018 00:03
    ricejasonf commented #432
  • Dec 20 2018 23:36
    pthom commented #432
  • Dec 20 2018 23:36
    pthom commented #432
  • Dec 20 2018 23:13
    ricejasonf commented #432
Louis Dionne
@ldionne
One problem is that Haskell does deep laziness, in the sense that every subexpressions of every expression is lazy. With a lazy adaptor, we can only get superficial laziness at one level.
Manu Sánchez
@Manu343726
Exactly. That's what I mean by reinventing the language. To make this really work in the most Haskell-like way, users should rely in the features provided here only.
Louis Dionne
@ldionne
I think one thing to reconsider is the value of laziness in a strict language like C++. It is obviously useful in some contexts, but it might not be worth the immense pain that you’re up to if you try to have deep laziness.
Conceptually, having deep laziness in C++ means to do the “evaluation” of lazy thunks manually, whereas it is done automatically in Haskell. Also, you won’t be memoizing the results of computations, which makes a lot of brilliant lazy patterns completely worthless.
My impression is that evaluating lazy thunks manually will be very painful from a programmer’s perspective.
Anyway, that’s the current state of my understanding of things. This is why Hana does not try to go lazy except in some simple cases (e.g. for conditional statements), and this is also why the usual Haskell concepts are broken up into more parts (Iterable, Foldable and Searchable instead of just Foldable in Haskell).
Louis Dionne
@ldionne
But I agree that laziness would be something nice to have. Also, I’d like to point out that this issue is really not limited to metaprogramming or implementing Haskell in C++. Indeed, the range-v3 people are bumping against similar issues, see ericniebler/range-v3#142.
Manu Sánchez
@Manu343726

Being frankly the only use case that comes to my mind for laziness (From the C++ point of view) are infinite ranges and related. In depth laziness and non-strict functions are cool, but their advantages may not worth the effort. Let's forget lazy for now (right fold included).

I'm gonna try to focus on translating the existing concepts to CL for now.

What I don't know is what to do with Turbo xD. I have a lot of plans for it, but it's a looooooooooong roadmap. But I will keep with it as an ideas "incubator". Algebraic datatypes as nested structs starts to look great, at least for me. But there's a lot of work to do first. Like Manu343726/Turbo#8
Louis Dionne
@ldionne
I think anything that tries to see how things would look with concepts is a good thing, since concepts are the future for C++. In the long term, I think even metaprogramming libraries will have to use Concepts (for the better). I’d be interested to watch your progress on this topic; please consider making your work in that direction publicly available on GitHub.
Also, if you keep on pushing in the direction of pure type-level metaprogramming (with Turbo), I’d suggest that you carefully take into account the possible compile-time penalty for recursively evaluating expressions through eval. I’m not sure whether your eval evaluates recursively, but it could be costly if it does. I don’t know for sure, but just be careful.
Nicola Bonelli
@awgn
Hi there!
Manu Sánchez
@Manu343726
So asking for feedback on twitter works after all :)
Nicola Bonelli
@awgn
Ahah well, after all the topic is pretty hot right now. Onestly I was interested in trying this chat 😅
Manu Sánchez
@Manu343726

:point_up: May 3 2015 6:26 AM

eval did full recursive evaluation at the beginning, but as Turbo evolved recursive evaluation has lost importance in favor of thinking of eval as a way to evaluate all kind of expressions. Should I evaluate any template parameters prior to evaluate the template itself? I'm not that sure these days. Not for non-function templates. Also those should be evaluated lazily, not just evaluate the whole parameter list prior to function evaluation as I currently do. That's one of the reasons I'm focusing the effort on having comfortable curryable metafunctions.

Louis Dionne
@ldionne
@awgn Hi!
@Manu343726 I don’t know if that might be of interest to you, but MPL11 has a curry metafunction here.
Manu Sánchez
@Manu343726
@ldionne what does ::type mean? If curry is evaluated without arguments returns curry itself, else the next one (via apply)?
Nicola Bonelli
@awgn
Manu, being lazy in your template mtp library means not accessing to ::type right?
Louis Dionne
@ldionne
MPL11 is lazy from the ground up (you can actually right fold infinite lists with it). It only manipulates what we call “boxed” values, i.e. values with a nested ::type. This is what curry<…>::type is; it just evaluates the curry<…> value itself. It does not perform any kind of computation.
I think I’m not being clear enough. 1 sec.
Manu Sánchez
@Manu343726
@ldionne that makes sense. I understood that pretty well from your readme, don't worry. So type there is to behave like a boxed entity.
Louis Dionne
@ldionne
Yeah, exactly.
In the same vein, you can see in the curry<1, f> specialization that I evaluate the metafunction class with f::type::template apply<x>. The f::type part means: “unbox the metafunction f”, and then call this with x.
Manu Sánchez
@Manu343726
@awgn for metafunctions, yes. If you write everything via metafunctions it behaves eager like Eric's Meta. But Turbo also supports metafunctions classes.
Nicola Bonelli
@awgn
I need to give a look at your libs guys, otherwise I risk to reinvent the wheel :-)
Manu Sánchez
@Manu343726

@ldionne got it thanks!

What I'm doing is to return a closure until the metafunctions accepts the arguments. That is, the metafunction is curryed until you enter all the arguments needed:

template<template<typename...> class Function>
struct curry
{
    template<typename... Args>
    struct apply
    {
        using f = just_t<Function, Args...>;

        template<typename F, bool is_function = has_type<F>::value>
        struct call
        {
            using type = typename F::type;
        };

        template<typename F>
        struct call<F, false>
        {
            struct type
            {
                template<typename... Tail>
                struct apply
                {
                    using type = eval_mc<curry, Args..., Tail...>;
                };
            };
        };

        using type = typename call<f>::type;
    };
};
just_t tries to instance a template with the given arguments, else returns Nothing. Of course Nothing is not a metafunction nor has a ::type member.
Louis Dionne
@ldionne
@awgn I looked at your Cat library, and it is not reinventing Hana in the following sense: Cat manipulates sequences whose length is known at runtime, whereas Hana manipulates sequences whose length is known at compile-time. This distinction makes a huge difference because it allows Hana sequences to hold objects with different types, but then you also lose a lot of properties like being able to append a runtime-known number of elements to a Hana sequence.
Manu Sánchez
@Manu343726
And to index those sequences at runtime :(
Louis Dionne
@ldionne
Yeah, but it only makes sense when you think about it; the type of the returned value would have to depend on a runtime integer, which is impossible. You need to use a dependently-typed language for that (Agda, Coq & al, I'm not too knowledgeable there).
@Manu343726 , How does your curry utility handles variadic metafunctions?
When does it stop evaluating? IIUC, it will stop at the first argument. For example, how would you curry the following:
template <typename ...T>
struct pack_size {
    using type = std::integral_constant<std::size_t, sizeof...(T)>;    
};
Nicola Bonelli
@awgn
Sorry guys my GF is reclaiming me... Talk later 😒
Manu Sánchez
@Manu343726
@ldionne good catch ;) It doesn't, since a variadic template is always instantiable regardless of the arguments. What I have is a Continue tag. $(f, a, b, c, Continue), where fis a variadic metafunction.
Louis Dionne
@ldionne
@Manu343726 From my current understanding, it is impossible to automatically curry variadic metafunctions (or functions for that matter). The user has to say "consider this function as a __n -ary function for currying".
How does the continue trick work?
Manu Sánchez
@Manu343726
Checking the back argument prior to evaluation. I have played with a Curry tag that comes at the beginning too, just to make the thing O(1).
Louis Dionne
@ldionne
Ok, so before you evaluate the thing, you check whether it's got a Continue tag at the end, and if so, you just return the expression as-is instead of fetching the nested ::type?
Manu Sánchez
@Manu343726
Exactly, I return a closure (The type struct in the false specialization of call above.
eval_mc means "evaluate metafunction class" just typename F::template apply<Args...>::type less ugly
Louis Dionne
@ldionne
Oh, ok I get it.
Manu Sánchez
@Manu343726
Hey, I finally got gcc-clite working. The latest release (gcc-clite 0.3) starts from GCC 4.8.0, so I'm not sure if this will work with hana since it relies on C++14. I will check the GCC features table now.
polymorphic lambdas 4.9 ;(
Louis Dionne
@ldionne
No, it will definitely not work with Hana. Actually, I’m working on a port of Hana for GCC 5 but it’s still not done.
Anything below GCC 5 is very unlikely to work. I’ve tried it before, but we have to reduce the functionality so much that it becomes less usable. For example, no generalized constexpr and no variable templates basically destroys Hana.
But GCC5 got all that, hence the ongoing port.
Manu Sánchez
@Manu343726
I haven't found any other experimental implementation of concepts lite. Nothing from the llvm guys.
Louis Dionne
@ldionne
Crap
Manu Sánchez
@Manu343726
There is a thread at the iso c++ google groups list on the topic: https://groups.google.com/a/isocpp.org/forum/#!topic/concepts/uNVfp04qN64