Jump to page: 1 2 3
Thread overview
RFC: StaticFilter, PApply, Compose, template predicates
Sep 04, 2011
David Nadlinger
Sep 04, 2011
David Nadlinger
Sep 04, 2011
Andrej Mitrovic
Sep 04, 2011
David Nadlinger
Sep 04, 2011
Andrej Mitrovic
Sep 04, 2011
David Nadlinger
Sep 04, 2011
Simen Kjaeraas
Sep 04, 2011
bearophile
Sep 04, 2011
David Nadlinger
Sep 04, 2011
dsimcha
Sep 05, 2011
Robert Jacques
Sep 05, 2011
bearophile
Sep 05, 2011
Simen Kjaeraas
Sep 05, 2011
Timon Gehr
Sep 05, 2011
Simen Kjaeraas
Sep 05, 2011
kenji hara
Sep 05, 2011
Timon Gehr
Sep 05, 2011
zeljkog
Sep 05, 2011
Timon Gehr
Sep 05, 2011
zeljkog
Sep 05, 2011
Timon Gehr
Sep 05, 2011
bearophile
Sep 05, 2011
bearophile
Sep 05, 2011
bearophile
Re: StaticFilter, PApply, Compose, template predicates
Sep 05, 2011
kennytm
Sep 05, 2011
kenji hara
Sep 05, 2011
Timon Gehr
Sep 05, 2011
David Nadlinger
Sep 05, 2011
Timon Gehr
September 04, 2011
As we currently aren't reviewing anything (We still need a review manager for David's RegionAllocator or whatever we decide to receive next? Do you want to get things going Jonathan? Should I do it again? Anybody else?), I thought I would take the opportunity to ask for comments on a few little template metaprogramming helpers:

https://gist.github.com/1191885

Besides a few helpers for manipulating/combining template predicates, the above link contains three main:

StaticFilter – like std.algorithm.filter, but for type tuples using template predicates.
PApply – like the unluckily named std.functional.curry, but for template parameters
Compose - alias Compose!(A, B, C) Comp; // Comp!D is now A!(B!(C!D)).

I had originally whipped these up on the fly while working on some metaprogramming-heavy code, but they have proven useful in other projects as well. What do you think? Would some of these be worthy additions to Phobos? Do you have similar stuff lying around in your own code?

Thanks,
David
September 04, 2011
I should also note that I ripped these out of an existing code base without thinking too much, feel free to ping me about any stupid documentation, etc. oversights.

David


On 9/4/11 2:46 AM, David Nadlinger wrote:
> As we currently aren't reviewing anything (We still need a review
> manager for David's RegionAllocator or whatever we decide to receive
> next? Do you want to get things going Jonathan? Should I do it again?
> Anybody else?), I thought I would take the opportunity to ask for
> comments on a few little template metaprogramming helpers:
>
> https://gist.github.com/1191885
>
> Besides a few helpers for manipulating/combining template predicates,
> the above link contains three main:
>
> StaticFilter – like std.algorithm.filter, but for type tuples using
> template predicates.
> PApply – like the unluckily named std.functional.curry, but for template
> parameters
> Compose - alias Compose!(A, B, C) Comp; // Comp!D is now A!(B!(C!D)).
>
> I had originally whipped these up on the fly while working on some
> metaprogramming-heavy code, but they have proven useful in other
> projects as well. What do you think? Would some of these be worthy
> additions to Phobos? Do you have similar stuff lying around in your own
> code?
>
> Thanks,
> David

September 04, 2011
I think `not` is already in std.functional, the others look very interesting though!
September 04, 2011
On 9/4/11 2:57 AM, Andrej Mitrovic wrote:
> I think `not` is already in std.functional, the others look very
> interesting though!

std.functional.not negates a function, my Not negates a template predicate. Should probably make that clearer, though…

David
September 04, 2011
Ooh ok. But how is it different from just using a bang? An example would be nice there.
September 04, 2011
On 9/4/11 3:04 AM, Andrej Mitrovic wrote:
> Ooh ok. But how is it different from just using a bang? An example
> would be nice there.

Imagine you have a template predicate »hasType«, which checks if the passed expression has a type:

---
template hasType(T...) if (T.length == 1) {
  enum hasType = is(typeof(T[0]));
}
---

Now, you want to get the elements from a type tuple that don't have a type (e.g. types themselves, and this is one of the situations that show how confusing the name »type tuple« really is). But you can't just do »StaticFilter!(!hasType, Tuple)«, because you can't just »negate a template« like this.

In this situation, Not makes sense: »StaticFilter(Not!hasType, Tuple)«. If D supported something like template literals, Not wouldn't be needed, but as we don't have them, I know no other (easy) way of achieving the same.

By the way, Not could also be implemented as:
---
template not(T...) if (T.length == 1 && is(typeof(!T[0]) : bool)) {
  enum bool not = !T[0];
}
alias PApply!(Compose, not) Not;
---

I felt this would be somewhat over the top though… ;)

David
September 04, 2011
On Sun, 04 Sep 2011 02:46:47 +0200, David Nadlinger <see@klickverbot.at> wrote:

> As we currently aren't reviewing anything (We still need a review manager for David's RegionAllocator or whatever we decide to receive next? Do you want to get things going Jonathan? Should I do it again? Anybody else?), I thought I would take the opportunity to ask for comments on a few little template metaprogramming helpers:
>
> https://gist.github.com/1191885
>
> Besides a few helpers for manipulating/combining template predicates, the above link contains three main:
>
> StaticFilter – like std.algorithm.filter, but for type tuples using template predicates.
> PApply – like the unluckily named std.functional.curry, but for template parameters
> Compose - alias Compose!(A, B, C) Comp; // Comp!D is now A!(B!(C!D)).
>
> I had originally whipped these up on the fly while working on some metaprogramming-heavy code, but they have proven useful in other projects as well. What do you think? Would some of these be worthy additions to Phobos? Do you have similar stuff lying around in your own code?

StaticFilter definitely should be in Phobos. StaticReduce too, but you
don't seem to have it on your list. I also often use StaticIota.

For more handy templates I feel should be in Phobos, see
Philippe Sigaud's dranges:

http://www.dsource.org/projects/dranges


-- 
  Simen
September 04, 2011
I am back.

Simen Kjaeraas:

> I also often use StaticIota.

I suggest to not add StaticIota, and improve foreach instead: http://d.puremagic.com/issues/show_bug.cgi?id=4085

Bye,
bearophile
September 04, 2011
On 9/5/11 1:05 AM, Simen Kjaeraas wrote:
> StaticFilter definitely should be in Phobos. StaticReduce too, but you
> don't seem to have it on your list. I also often use StaticIota.

I have a StaticReduce lying around as well, but didn't include it in the snippet as I have used it exactly once so far, and wanted to keep the list short. It should probably be in Phobos though, even if only to compliment staticMap (the name of which really should be capitalized, I think); I'll add it to the Gist.

> For more handy templates I feel should be in Phobos, see
> Philippe Sigaud's dranges:
>
> http://www.dsource.org/projects/dranges

Wow, thanks for the tip, I vaguely remembered it being talked about here, but didn't know it includes so many metaprogramming goodies. From quickly skimming the code in templates.d, it seems like some of the templates unnecessarily rely on string mixins though, which considerably reduces their value. For example, Philippe's take on »Compose« will only work if the templates in question are from drange.template as well (resp. from modules imported by it), similar to the restrictions for std.functional string lambdas.

David
September 04, 2011
== Quote from Simen Kjaeraas (simen.kjaras@gmail.com)'s article
> StaticFilter definitely should be in Phobos. StaticReduce too, but you
> don't seem to have it on your list. I also often use StaticIota.
> For more handy templates I feel should be in Phobos, see
> Philippe Sigaud's dranges:
> http://www.dsource.org/projects/dranges
> -- =
>    Simen

Seconded.  StaticIota is extremely useful for loop unrolling optimizations, e.g.:

T sum(T)(T[] nums) {
    enum nILP = 6;
    auto ilpTuple = StaticIota!nILP;
    T[nILP] ret = 0;

    for(size_t i = 0; i + nILP < nums.length; i += nILP) {
        foreach(j; ilpTuple) {
            // Static, automatically unrolled.
            ret[j] += nums[i + j];
        }
    }

    foreach(i; nums.length / nILP * nILP..nums.length) {
        ret[0] += nums[i];
    }

    foreach(i; 1..nILP) {
        ret[0] += ret[i];
    }

    return ret[0];
}
« First   ‹ Prev
1 2 3