Re: cannot use local f as parameter to non-global template

2018-12-10 Thread Paul Backus via Digitalmars-d-learn

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.


Re: cannot use local f as parameter to non-global template

2018-12-10 Thread aliak via Digitalmars-d-learn

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:

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.


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?


Re: cannot use local f as parameter to non-global template

2018-12-08 Thread Paul Backus via Digitalmars-d-learn

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.


cannot use local f as parameter to non-global template

2018-12-08 Thread aliak via Digitalmars-d-learn
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


Re: template instance cannot use local 'f' as parameter to non-global template

2011-07-13 Thread Trass3r

Anybody an idea?


Re: template instance cannot use local 'f' as parameter to non-global template

2011-07-13 Thread Stephan

On 12.07.2011 15:06, Trass3r wrote:

Is this a bug? If not, how do you make it work?

void h() {}

class Bla
{
mixin wrap!h;
}

mixin template wrap(alias f)
{
void blub(alias g = f)()
{
}
}

void main()
{
Bla b = new Bla();
b.blub();
}

test.d(18): Error: template instance cannot use local 'f' as parameter
to non-global template blub(alias g = f)
test.d(18): Error: template instance forward reference of f
test.d(18): Error: template instance test.Bla.wrap!(h).blub!(f) error
instantiating


I am not sure but i am not that used to those template aliases anyway.


Re: template instance cannot use local 'f' as parameter to non-global template

2011-07-13 Thread Steven Schveighoffer

On Tue, 12 Jul 2011 09:06:56 -0400, Trass3r u...@known.com wrote:


Is this a bug? If not, how do you make it work?

void h() {}

class Bla
{
mixin wrap!h;
}

mixin template wrap(alias f)
{
void blub(alias g = f)()
{
}
}

void main()
{
Bla b = new Bla();
b.blub();
}

test.d(18): Error: template instance cannot use local 'f' as parameter  
to non-global template blub(alias g = f)

test.d(18): Error: template instance forward reference of f
test.d(18): Error: template instance test.Bla.wrap!(h).blub!(f) error  
instantiating


I've seen this error before...

*searches memory and old code*

Here you go: http://d.puremagic.com/issues/show_bug.cgi?id=3051

As a workaround, is there a reason you need blub to be parameterized?  I  
mean, f is already part of the template.


-Steve


Re: template instance cannot use local 'f' as parameter to non-global template

2011-07-13 Thread Trass3r
Am 13.07.2011, 16:02 Uhr, schrieb Steven Schveighoffer  
schvei...@yahoo.com:



void h() {}

class Bla
{
mixin wrap!h;
}

mixin template wrap(alias f)
{
void blub(alias g = f)()
{

g();

}
}


As a workaround, is there a reason you need blub to be parameterized?  I  
mean, f is already part of the template.


Yep, a default function is passed to wrap and in most cases blub just  
calls that one.

But sometimes I need blub to use a function other than the default one.


Re: template instance cannot use local 'f' as parameter to non-global template

2011-07-13 Thread Tyro[a.c.edwards]

On 7/13/2011 11:35 PM, Trass3r wrote:

Am 13.07.2011, 16:02 Uhr, schrieb Steven Schveighoffer
schvei...@yahoo.com:


void h() {}

class Bla
{
mixin wrap!h;
}

mixin template wrap(alias f)
{
void blub(alias g = f)()
{

g();

}
}



As a workaround, is there a reason you need blub to be parameterized?
I mean, f is already part of the template.


Yep, a default function is passed to wrap and in most cases blub just
calls that one.
But sometimes I need blub to use a function other than the default one.


Don't know it this is the right answer or a possible bug but it does the 
trick:


void h() { import std.stdio; write(h()); }

class Bla
{
mixin wrap!h;
}

mixin template wrap(alias f)
{
void blub(typeof(f) g = f)
{
g();
}
}

void main()
{
Bla b = new Bla();
b.blub();
}


Re: template instance cannot use local 'f' as parameter to non-global template

2011-07-13 Thread Trass3r

Am 13.07.2011, 16:58 Uhr, schrieb Tyro[a.c.edwards] nos...@home.com:
Don't know it this is the right answer or a possible bug but it does the  
trick:


void h() { import std.stdio; write(h()); }

class Bla
{
 mixin wrap!h;
}

mixin template wrap(alias f)
{
 void blub(typeof(f) g = f)
 {
g();
 }
}

void main()
{
 Bla b = new Bla();
 b.blub();
}


Thanks!
Unfortunately it doesn't work with more complex functions:

Error: arithmetic/string type expected for value-parameter, not cl_errcode  
C function(cl_program program, uint param_name, ulong param_value_size,  
void* param_value, ulong* param_value_size_ret)


Re: template instance cannot use local 'f' as parameter to non-global template

2011-07-13 Thread Trass3r

I've seen this error before...

*searches memory and old code*

Here you go: http://d.puremagic.com/issues/show_bug.cgi?id=3051


I think this is yet another issue.
The inner template argument is not something on the stack but it is a  
template argument.


Re: template instance cannot use local 'f' as parameter to non-global template

2011-07-13 Thread Tyro[a.c.edwards]

On 7/14/2011 12:24 AM, Trass3r wrote:

Am 13.07.2011, 16:58 Uhr, schrieb Tyro[a.c.edwards] nos...@home.com:

Don't know it this is the right answer or a possible bug but it does
the trick:

void h() { import std.stdio; write(h()); }

class Bla
{
mixin wrap!h;
}

mixin template wrap(alias f)
{
void blub(typeof(f) g = f)
{
g();
}
}

void main()
{
Bla b = new Bla();
b.blub();
}


Thanks!
Unfortunately it doesn't work with more complex functions:

Error: arithmetic/string type expected for value-parameter, not
cl_errcode C function(cl_program program, uint param_name, ulong
param_value_size, void* param_value, ulong* param_value_size_ret)



I gusss the simplest example of the problem you're experiencing would be 
this:


void h() { import std.stdio; write(h()); }

void function() fp = h;

class Bla
{
mixin wrap!(fp);
}

mixin template wrap(alias f)
{
void blub()
{
typeof(f) g = f;
g();  // --- source of error [1]
}
}

void main()
{
Bla b = new Bla();
b.blub();
}

edit1.d(19): Error: function expected before (), not g of type uint* C 
function()*


[1] Here you are calling a function pointer which simply returns the 
address of the function... hence your error!


Try calling the function (differencing the pointer as such: (*g)()) and 
your problem is solved.


Re: template instance cannot use local 'f' as parameter to non-global template

2011-07-13 Thread Tyro[a.c.edwards]

On 7/14/2011 12:24 AM, Trass3r wrote:

Am 13.07.2011, 16:58 Uhr, schrieb Tyro[a.c.edwards] nos...@home.com:

Don't know it this is the right answer or a possible bug but it does
the trick:

void h() { import std.stdio; write(h()); }

class Bla
{
mixin wrap!h;
}

mixin template wrap(alias f)
{
void blub(typeof(f) g = f)
{
g();
}
}

void main()
{
Bla b = new Bla();
b.blub();
}


Thanks!
Unfortunately it doesn't work with more complex functions:

Error: arithmetic/string type expected for value-parameter, not
cl_errcode C function(cl_program program, uint param_name, ulong
param_value_size, void* param_value, ulong* param_value_size_ret)


I guess the simplest example of the problem you're experiencing would be 
this:


void h() { import std.stdio; write(h()); }

void function() fp = h;

class Bla
{
mixin wrap!(fp);
}

mixin template wrap(alias f)
{
void blub()
{
typeof(f) g = f;
g();  // --- source of error [1]
}
}

void main()
{
Bla b = new Bla();
b.blub();
}

edit1.d(19): Error: function expected before (), not g of type void 
function()*


[1] Here you are calling a function pointer which simply returns the 
address of the function... hence your error!


Try calling the function pointed to by differencing the pointer as such: 
(*g)() and your problem is solved.


template instance cannot use local 'f' as parameter to non-global template

2011-07-12 Thread Trass3r

Is this a bug? If not, how do you make it work?

void h() {}

class Bla
{
mixin wrap!h;
}

mixin template wrap(alias f)
{
void blub(alias g = f)()
{
}
}

void main()
{
Bla b = new Bla();
b.blub();
}

test.d(18): Error: template instance cannot use local 'f' as parameter to  
non-global template blub(alias g = f)

test.d(18): Error: template instance forward reference of f
test.d(18): Error: template instance test.Bla.wrap!(h).blub!(f) error  
instantiating