| Thread overview | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 05, 2016 Template currying | ||||
|---|---|---|---|---|
| ||||
So I was working on a parser combinator library, where the combinators take parsers as template argument. It works well until recently I decided to change the parsers so they would take Ranges instead of just strings.
The combinator used to look like:
template Comb(alias parser1, alias parser2)
Now it looks like
template Comb(alias parser1, alias parser2, Range)
And I want to have the compile deduce the Range template arguments, so I don't need to change the code that uses them. But I found out it's hard to partially instantiate templates.
It's OK to do that at the call site, e.g. Comb!(a, b)(range) works without specifying the Range. But sometimes I want to alias the result parser so I can use it at multiple places, but
alias new_parser = Comb!(a, b);
doesn't work.
I need either to define Comb differently:
template Comb(alias p1, alias p2) {
template Comb(Range) {
or not use alias:
template new_parser(alias p1, alias p2){
alias new_parser(Range) = Comb!(p1, p2, Range); //Something like this, not tested
}
I think it would be really nice if alias can be automatically translated to the latter one. Or maybe we can have something like
template Curry(alias tmpl, Args1...) {
alias Curry(Args2...) = tmpl!(Args1~Args2); //Pseudocode
}
in the phobos.
| ||||
May 05, 2016 Re: Template currying | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Yuxuan Shui | On Thursday, 5 May 2016 at 20:17:08 UTC, Yuxuan Shui wrote:
> So I was working on a parser combinator library, where the combinators take parsers as template argument. It works well until recently I decided to change the parsers so they would take Ranges instead of just strings.
>
> The combinator used to look like:
>
> template Comb(alias parser1, alias parser2)
>
> Now it looks like
>
> template Comb(alias parser1, alias parser2, Range)
>
> And I want to have the compile deduce the Range template arguments, so I don't need to change the code that uses them. But I found out it's hard to partially instantiate templates.
>
> It's OK to do that at the call site, e.g. Comb!(a, b)(range) works without specifying the Range. But sometimes I want to alias the result parser so I can use it at multiple places, but
>
> alias new_parser = Comb!(a, b);
>
> doesn't work.
>
> I need either to define Comb differently:
>
> template Comb(alias p1, alias p2) {
> template Comb(Range) {
>
> or not use alias:
>
> template new_parser(alias p1, alias p2){
> alias new_parser(Range) = Comb!(p1, p2, Range); //Something like this, not tested
> }
>
> I think it would be really nice if alias can be automatically translated to the latter one. Or maybe we can have something like
>
> template Curry(alias tmpl, Args1...) {
> alias Curry(Args2...) = tmpl!(Args1~Args2); //Pseudocode
> }
>
> in the phobos.
It's hard to help without a minimal working example (maybe something with just the body).
If you mean that "alias new_parser = Comb!(a, b);" generates an error maybe that's because the correct syntax is "alias new_parser(Range) = Comb!(a, b);" ?
One issue you may encounter is that template parameter deduction (that's called IFTI I think) can fail with an alias (so partially specialized template/templatized function, etc).
| |||
May 05, 2016 Re: Template currying | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ed | On Thursday, 5 May 2016 at 21:54:29 UTC, Ed wrote:
> On Thursday, 5 May 2016 at 20:17:08 UTC, Yuxuan Shui wrote:
>> [...]
>
> It's hard to help without a minimal working example (maybe something with just the body).
>
> If you mean that "alias new_parser = Comb!(a, b);" generates an error maybe that's because the correct syntax is "alias new_parser(Range) = Comb!(a, b);" ?
>
> One issue you may encounter is that template parameter deduction (that's called IFTI I think) can fail with an alias (so partially specialized template/templatized function, etc).
Simple example:
int a(int b, T)(T c){return 0;}
It's fine to:
a!1(2);
But:
alias A = a!1;
Would fail.
| |||
May 05, 2016 Re: Template currying | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Yuxuan Shui | On Thursday, 5 May 2016 at 22:53:01 UTC, Yuxuan Shui wrote:
> On Thursday, 5 May 2016 at 21:54:29 UTC, Ed wrote:
>> On Thursday, 5 May 2016 at 20:17:08 UTC, Yuxuan Shui wrote:
>>> [...]
>>
>> It's hard to help without a minimal working example (maybe something with just the body).
>>
>> If you mean that "alias new_parser = Comb!(a, b);" generates an error maybe that's because the correct syntax is "alias new_parser(Range) = Comb!(a, b);" ?
>>
>> One issue you may encounter is that template parameter deduction (that's called IFTI I think) can fail with an alias (so partially specialized template/templatized function, etc).
>
> Simple example:
>
> int a(int b, T)(T c){return 0;}
>
> It's fine to:
>
> a!1(2);
>
> But:
>
> alias A = a!1;
>
> Would fail.
alias aa(T) = a!(1,T);
aa!ubyte(2);
Your alias declaration is not correct.
| |||
May 05, 2016 Re: Template currying | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ed | On Thursday, 5 May 2016 at 23:12:40 UTC, Ed wrote:
> On Thursday, 5 May 2016 at 22:53:01 UTC, Yuxuan Shui wrote:
>> On Thursday, 5 May 2016 at 21:54:29 UTC, Ed wrote:
>>> On Thursday, 5 May 2016 at 20:17:08 UTC, Yuxuan Shui wrote:
>>>> [...]
>>>
>>> It's hard to help without a minimal working example (maybe something with just the body).
>>>
>>> If you mean that "alias new_parser = Comb!(a, b);" generates an error maybe that's because the correct syntax is "alias new_parser(Range) = Comb!(a, b);" ?
>>>
>>> One issue you may encounter is that template parameter deduction (that's called IFTI I think) can fail with an alias (so partially specialized template/templatized function, etc).
>>
>> Simple example:
>>
>> int a(int b, T)(T c){return 0;}
>>
>> It's fine to:
>>
>> a!1(2);
>>
>> But:
>>
>> alias A = a!1;
>>
>> Would fail.
>
> alias aa(T) = a!(1,T);
> aa!ubyte(2);
>
> Your alias declaration is not correct.
As you can see in my first post, I know how to make this work. I just think it'd be nice if compiler can do this automatically.
Anothor point is that, what if I want to use partially instantiated templates as template arguments?
| |||
May 05, 2016 Re: Template currying | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Yuxuan Shui | On Thursday, 5 May 2016 at 23:19:59 UTC, Yuxuan Shui wrote:
> On Thursday, 5 May 2016 at 23:12:40 UTC, Ed wrote:
>> On Thursday, 5 May 2016 at 22:53:01 UTC, Yuxuan Shui wrote:
>>> On Thursday, 5 May 2016 at 21:54:29 UTC, Ed wrote:
>>>> On Thursday, 5 May 2016 at 20:17:08 UTC, Yuxuan Shui wrote:
>>>>> [...]
>>>>
>>>> It's hard to help without a minimal working example (maybe something with just the body).
>>>>
>>>> If you mean that "alias new_parser = Comb!(a, b);" generates an error maybe that's because the correct syntax is "alias new_parser(Range) = Comb!(a, b);" ?
>>>>
>>>> One issue you may encounter is that template parameter deduction (that's called IFTI I think) can fail with an alias (so partially specialized template/templatized function, etc).
>>>
>>> Simple example:
>>>
>>> int a(int b, T)(T c){return 0;}
>>>
>>> It's fine to:
>>>
>>> a!1(2);
>>>
>>> But:
>>>
>>> alias A = a!1;
>>>
>>> Would fail.
>>
>> alias aa(T) = a!(1,T);
>> aa!ubyte(2);
>>
>> Your alias declaration is not correct.
>
> As you can see in my first post, I know how to make this work. I just think it'd be nice if compiler can do this automatically.
>
> Anothor point is that, what if I want to use partially instantiated templates as template arguments?
See this example:
int a(alias f)(){return f(3);}
int b(int z, T)(T c){return c;}
void main() {
a!(b!1)();
}
It'd really nice if this just works, or if there's something called Curry which I can use like this:
a!(Curry!(b, 1))
| |||
May 05, 2016 Re: Template currying | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Yuxuan Shui | On Thursday, 5 May 2016 at 23:19:59 UTC, Yuxuan Shui wrote:
> On Thursday, 5 May 2016 at 23:12:40 UTC, Ed wrote:
>> On Thursday, 5 May 2016 at 22:53:01 UTC, Yuxuan Shui wrote:
>>> On Thursday, 5 May 2016 at 21:54:29 UTC, Ed wrote:
>>>> On Thursday, 5 May 2016 at 20:17:08 UTC, Yuxuan Shui wrote:
>>>>> [...]
>>>>
>>>> It's hard to help without a minimal working example (maybe something with just the body).
>>>>
>>>> If you mean that "alias new_parser = Comb!(a, b);" generates an error maybe that's because the correct syntax is "alias new_parser(Range) = Comb!(a, b);" ?
>>>>
>>>> One issue you may encounter is that template parameter deduction (that's called IFTI I think) can fail with an alias (so partially specialized template/templatized function, etc).
>>>
>>> Simple example:
>>>
>>> int a(int b, T)(T c){return 0;}
>>>
>>> It's fine to:
>>>
>>> a!1(2);
>>>
>>> But:
>>>
>>> alias A = a!1;
>>>
>>> Would fail.
>>
>> alias aa(T) = a!(1,T);
>> aa!ubyte(2);
>>
>> Your alias declaration is not correct.
>
> As you can see in my first post, I know how to make this work. I just think it'd be nice if compiler can do this automatically.
>
> Anothor point is that, what if I want to use partially instantiated templates as template arguments?
My bad, I didn't read carefully "or not use alias:".
With alias template parameter you can pass template:
------
import std.stdio;
template Foo(T,U){ T pop(){return T.max;}}
alias Partial(U) = Foo!(U, string);
auto bar(alias Whatever)()
{
alias instance = Whatever!int;
return instance.pop;
}
void main(string[] args)
{
writeln(bar!(Partial)());
}
------
for example.
| |||
May 05, 2016 Re: Template currying | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ed | On Thursday, 5 May 2016 at 23:38:38 UTC, Ed wrote:
> On Thursday, 5 May 2016 at 23:19:59 UTC, Yuxuan Shui wrote:
>> On Thursday, 5 May 2016 at 23:12:40 UTC, Ed wrote:
>>> On Thursday, 5 May 2016 at 22:53:01 UTC, Yuxuan Shui wrote:
>>>> [...]
>>>
>>> alias aa(T) = a!(1,T);
>>> aa!ubyte(2);
>>>
>>> Your alias declaration is not correct.
>>
>> As you can see in my first post, I know how to make this work. I just think it'd be nice if compiler can do this automatically.
>>
>> Anothor point is that, what if I want to use partially instantiated templates as template arguments?
>
> My bad, I didn't read carefully "or not use alias:".
> With alias template parameter you can pass template:
>
> ------
> import std.stdio;
>
> template Foo(T,U){ T pop(){return T.max;}}
>
> alias Partial(U) = Foo!(U, string);
>
> auto bar(alias Whatever)()
> {
> alias instance = Whatever!int;
> return instance.pop;
> }
>
> void main(string[] args)
> {
> writeln(bar!(Partial)());
> }
> ------
>
>
Right, Partial!() works. I just want something more generic, like the Curry I proposed.
And I still think let the compiler do it is a good idea, because this could removes special cases in template arguments deduction
| |||
May 05, 2016 Re: Template currying | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Yuxuan Shui | On Thursday, 5 May 2016 at 23:33:07 UTC, Yuxuan Shui wrote:
> It'd really nice if this just works,
That's clear that you've never been stuck in the fat mud of imperative and OO programming styles. You don't realize (anymore ?) how lucky we are with D templates, compared to other languages! Maybe you come from C++, so that's not so obvious for you but with my background I'm still amused when I see people complaining about such details. ^^
Anyway, you can open a enhancement request and pray...
| |||
May 06, 2016 Re: Template currying | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ed | On Thursday, 5 May 2016 at 23:46:59 UTC, Ed wrote: > On Thursday, 5 May 2016 at 23:33:07 UTC, Yuxuan Shui wrote: >> It'd really nice if this just works, > > That's clear that you've never been stuck in the fat mud of imperative and OO programming styles. You don't realize (anymore ?) how lucky we are with D templates, compared to other languages! Maybe you come from C++, so that's not so obvious for you but with my background I'm still amused when I see people complaining about such details. ^^ Yes, I do appreciate the power of D, I just want it to be BETTER. > > Anyway, you can open a enhancement request and pray... I'll do that, but I just want to see some feedback on this idea.... | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply