digitalmars.D.learn - cannot use local f as parameter to non-global template
- aliak (34/34) Dec 08 2018 Hi, I'm wondering about why this happens in a certain situation
- Paul Backus (12/20) Dec 08 2018 The "de-sugared" version of your second `match` function looks
- aliak (14/36) Dec 10 2018 Ah, that's a good way of breaking it down. But ok, so then the
- Paul Backus (8/21) Dec 10 2018 Holder!f is a type, not a delegate, so passing it as a parameter
Hi, I'm wondering about why this happens in a certain situation and not another. I have the following code: struct Holder(alias fun) { alias T = typeof(fun()); T get() { return fun(); } alias get this; } template match(handlers...) { auto match(T)(T holder) { return handlers[0](holder); } } void main() { int f() { return i7 } auto value = Holder!f().match!( (int a) => f() ); } This compiles fine. However, if I change the match template to: template match(handlers...) { auto match(alias f)(Holder!f holder) { return handlers[0](holder); } } Notice the template parameter of the eponymous match is an alias now, and the function parameter is typed as a Holder. The error you get is basically because of bug 5710 [0] I guess. But I'm confused as to why the same thing doesn't then happen when using match(T) as opposed to match(alias f)? I can work around it by have a template constraint on match of course. But still curious why one version works and the other not, they both have to access the same frame+context data at the end of the day. [0]: https://issues.dlang.org/show_bug.cgi?id=5710
Dec 08 2018
On Saturday, 8 December 2018 at 09:57:29 UTC, aliak wrote:This compiles fine. However, if I change the match template to: template match(handlers...) { auto match(alias f)(Holder!f holder) { return handlers[0](holder); } } Notice the template parameter of the eponymous match is an alias now, and the function parameter is typed as a Holder.The "de-sugared" version of your second `match` function looks like this: template match(handlers...) { template match(alias f) { auto match(Holder!f holder) { return handlers[0](holder); } } } Notice the second template nested inside the first. That's the "non-gloal template" the error is complaining about.
Dec 08 2018
On Saturday, 8 December 2018 at 14:21:01 UTC, Paul Backus wrote:On Saturday, 8 December 2018 at 09:57:29 UTC, aliak wrote:Ah, that's a good way of breaking it down. But ok, so then the other version would be lowered to: template match(handlers...) { template match(T) { auto match(T holder) { return handlers[0](holder); } } } So now the second template is accessing a T, which is actually a Holder!f right? But doing that makes it "work". Even though the number of "contexts" needed to execute "handlers[0](holder)" is the same, right?This compiles fine. However, if I change the match template to: template match(handlers...) { auto match(alias f)(Holder!f holder) { return handlers[0](holder); } } Notice the template parameter of the eponymous match is an alias now, and the function parameter is typed as a Holder.The "de-sugared" version of your second `match` function looks like this: template match(handlers...) { template match(alias f) { auto match(Holder!f holder) { return handlers[0](holder); } } } Notice the second template nested inside the first. That's the "non-gloal template" the error is complaining about.
Dec 10 2018
On Monday, 10 December 2018 at 16:15:36 UTC, aliak wrote:Ah, that's a good way of breaking it down. But ok, so then the other version would be lowered to: template match(handlers...) { template match(T) { auto match(T holder) { return handlers[0](holder); } } } So now the second template is accessing a T, which is actually a Holder!f right? But doing that makes it "work". Even though the number of "contexts" needed to execute "handlers[0](holder)" is the same, right?Holder!f is a type, not a delegate, so passing it as a parameter to a non-global template is fine. Issue 5710 only applies to delegates passed directly as parameters. Trying to reason about the "number of contexts" required is a waste of time. There's no logical, principled reason why one works and the other doesn't. It's purely an artifact of details in the compiler implementation.
Dec 10 2018