Re: Allowing "fall through" of attributes

2016-07-20 Thread Ali Çehreli via Digitalmars-d-learn

On 07/19/2016 08:55 AM, Rufus Smith wrote:

I have some functions that take other functions. I would like the
attributes to be able to "fall" through so I get overload like behavior.
I only care that I am passing a function, not if it is shared,
extern(C), pure, @nogc, etc.

void foo(R, A...)(R function(A) bar)
{
alias type = typeof(bar);
pragma(msg, type);
// does magic with bar
}

foo never uses the attributes of bar explicitly. It uses type to
instantiate other functions like bar. I have to create a foo for each
attribute combination, which is not worth while. The code seems to break
only for extern, the best I can tell, most attributes do pass through.
But type does not contain these attributes.



functionAttributes may be useful. SetFunctionAttributes has an example:

  https://dlang.org/phobos/std_traits.html#SetFunctionAttributes

Ali




Re: Allowing "fall through" of attributes

2016-07-19 Thread Rufus Smith via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 17:10:35 UTC, Lodovico Giaretta wrote:

On Tuesday, 19 July 2016 at 17:05:55 UTC, Rufus Smith wrote:
On Tuesday, 19 July 2016 at 16:59:48 UTC, Lodovico Giaretta 
wrote:

On Tuesday, 19 July 2016 at 16:50:56 UTC, Rufus Smith wrote:
On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta 
wrote:

[...]


But this doesn't create a function with all the attributes 
of the original? Just one that has the same return type and 
parameters. What if Fun is pure or extern(C) or some other 
attributes? I'd like to create a function that is exactly 
the same in all regards as the original.


Sorry, I misunderstood your question.
With the method I showed you, if the function is @safe, pure, 
@nogc or nothrow, foo will infer those attributes. But only 
if the operations you do in foo (apart from calling bar) are 
themselves @safe, pure, @nogc or nothrow.
For other things, like extern(C), I don't think there's a 
simple solution; but I'm not an expert, so I hope someone 
else will give you a better answer.


What is strange is I cannot even pass an extern(C) function to 
foo.


void foo(R, A...)(R function(A) bar);

extern(C) void bar();

foo()

fails. Remove extern and it passes. I have not figured out how 
to allow for extern(C) functions to be passed.


That's because an extern function must be called with a 
different code. So it cannot be cast to a non-extern(C) 
function pointer, which is what your foo accepts. If you follow 
my advice, and make the entire function type a parameter of 
foo, then foo will at least accept your extern(C) function, but 
it will not be extern(C) itself.


I don't want it to be cast to a non-extern function. What I want 
to do is create the exact same type of function that is passed to 
the template except modify the arguments.


If I use a general parameter for the function, it accepts 
extern(C), but I can't construct a function with it.


mixin("alias F = extern("~functionLinkage!Q~") 
"~(ReturnType!Q).stringof~" 
function"~(Parameters!Q).stringof~";");


gives me a type that looks to be what I want but I can't really 
use it unless I want to declare the function that does the work 
inside foo as mixin string.


One can't do extern(functionLinkage!Q) void baz() to create baz 
with the proper linkage ;/


It looks like I might have to go the mixin way ;/ Going to be 
messy ;/







Re: Allowing "fall through" of attributes

2016-07-19 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 17:05:55 UTC, Rufus Smith wrote:
On Tuesday, 19 July 2016 at 16:59:48 UTC, Lodovico Giaretta 
wrote:

On Tuesday, 19 July 2016 at 16:50:56 UTC, Rufus Smith wrote:
On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta 
wrote:

[...]


But this doesn't create a function with all the attributes of 
the original? Just one that has the same return type and 
parameters. What if Fun is pure or extern(C) or some other 
attributes? I'd like to create a function that is exactly the 
same in all regards as the original.


Sorry, I misunderstood your question.
With the method I showed you, if the function is @safe, pure, 
@nogc or nothrow, foo will infer those attributes. But only if 
the operations you do in foo (apart from calling bar) are 
themselves @safe, pure, @nogc or nothrow.
For other things, like extern(C), I don't think there's a 
simple solution; but I'm not an expert, so I hope someone else 
will give you a better answer.


What is strange is I cannot even pass an extern(C) function to 
foo.


void foo(R, A...)(R function(A) bar);

extern(C) void bar();

foo()

fails. Remove extern and it passes. I have not figured out how 
to allow for extern(C) functions to be passed.


That's because an extern function must be called with a different 
code. So it cannot be cast to a non-extern(C) function pointer, 
which is what your foo accepts. If you follow my advice, and make 
the entire function type a parameter of foo, then foo will at 
least accept your extern(C) function, but it will not be 
extern(C) itself.


Re: Allowing "fall through" of attributes

2016-07-19 Thread Rufus Smith via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 16:59:48 UTC, Lodovico Giaretta wrote:

On Tuesday, 19 July 2016 at 16:50:56 UTC, Rufus Smith wrote:
On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta 
wrote:

[...]


But this doesn't create a function with all the attributes of 
the original? Just one that has the same return type and 
parameters. What if Fun is pure or extern(C) or some other 
attributes? I'd like to create a function that is exactly the 
same in all regards as the original.


Sorry, I misunderstood your question.
With the method I showed you, if the function is @safe, pure, 
@nogc or nothrow, foo will infer those attributes. But only if 
the operations you do in foo (apart from calling bar) are 
themselves @safe, pure, @nogc or nothrow.
For other things, like extern(C), I don't think there's a 
simple solution; but I'm not an expert, so I hope someone else 
will give you a better answer.


What is strange is I cannot even pass an extern(C) function to 
foo.


void foo(R, A...)(R function(A) bar);

extern(C) void bar();

foo()

fails. Remove extern and it passes. I have not figured out how to 
allow for extern(C) functions to be passed.


Re: Allowing "fall through" of attributes

2016-07-19 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 16:50:56 UTC, Rufus Smith wrote:
On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta 
wrote:

On Tuesday, 19 July 2016 at 15:55:02 UTC, Rufus Smith wrote:
I have some functions that take other functions. I would like 
the attributes to be able to "fall" through so I get overload 
like behavior. I only care that I am passing a function, not 
if it is shared, extern(C), pure, @nogc, etc.


void foo(R, A...)(R function(A) bar)
{
   alias type = typeof(bar);
   pragma(msg, type);
   // does magic with bar
}

foo never uses the attributes of bar explicitly. It uses type 
to instantiate other functions like bar. I have to create a 
foo for each attribute combination, which is not worth while. 
The code seems to break only for extern, the best I can tell, 
most attributes do pass through. But type does not contain 
these attributes.


You shall do something like this (please note that I didn't 
check the docs while writing this; you shall definitely have a 
look at std.traits and consider the following as pseudo-code 
and not actual D):


void foo(Fun)(Fun bar)
if (isSomeFunction!Fun)   // your constraint that bar is a 
function

{
// how to get your R and A types, if you need them:
alias R = ReturnType!bar;
alias A = Parameters!bar;

alias type = Fun;
pragma(msg, type);

// do some magic
}


But this doesn't create a function with all the attributes of 
the original? Just one that has the same return type and 
parameters. What if Fun is pure or extern(C) or some other 
attributes? I'd like to create a function that is exactly the 
same in all regards as the original.


Sorry, I misunderstood your question.
With the method I showed you, if the function is @safe, pure, 
@nogc or nothrow, foo will infer those attributes. But only if 
the operations you do in foo (apart from calling bar) are 
themselves @safe, pure, @nogc or nothrow.
For other things, like extern(C), I don't think there's a simple 
solution; but I'm not an expert, so I hope someone else will give 
you a better answer.


Re: Allowing "fall through" of attributes

2016-07-19 Thread Rufus Smith via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta wrote:

On Tuesday, 19 July 2016 at 15:55:02 UTC, Rufus Smith wrote:
I have some functions that take other functions. I would like 
the attributes to be able to "fall" through so I get overload 
like behavior. I only care that I am passing a function, not 
if it is shared, extern(C), pure, @nogc, etc.


void foo(R, A...)(R function(A) bar)
{
   alias type = typeof(bar);
   pragma(msg, type);
   // does magic with bar
}

foo never uses the attributes of bar explicitly. It uses type 
to instantiate other functions like bar. I have to create a 
foo for each attribute combination, which is not worth while. 
The code seems to break only for extern, the best I can tell, 
most attributes do pass through. But type does not contain 
these attributes.


You shall do something like this (please note that I didn't 
check the docs while writing this; you shall definitely have a 
look at std.traits and consider the following as pseudo-code 
and not actual D):


void foo(Fun)(Fun bar)
if (isSomeFunction!Fun)   // your constraint that bar is a 
function

{
// how to get your R and A types, if you need them:
alias R = ReturnType!bar;
alias A = Parameters!bar;

alias type = Fun;
pragma(msg, type);

// do some magic
}


But this doesn't create a function with all the attributes of the 
original? Just one that has the same return type and parameters. 
What if Fun is pure or extern(C) or some other attributes? I'd 
like to create a function that is exactly the same in all regards 
as the original.




Re: Allowing "fall through" of attributes

2016-07-19 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 19 July 2016 at 15:55:02 UTC, Rufus Smith wrote:
I have some functions that take other functions. I would like 
the attributes to be able to "fall" through so I get overload 
like behavior. I only care that I am passing a function, not if 
it is shared, extern(C), pure, @nogc, etc.


void foo(R, A...)(R function(A) bar)
{
   alias type = typeof(bar);
   pragma(msg, type);
   // does magic with bar
}

foo never uses the attributes of bar explicitly. It uses type 
to instantiate other functions like bar. I have to create a foo 
for each attribute combination, which is not worth while. The 
code seems to break only for extern, the best I can tell, most 
attributes do pass through. But type does not contain these 
attributes.


You shall do something like this (please note that I didn't check 
the docs while writing this; you shall definitely have a look at 
std.traits and consider the following as pseudo-code and not 
actual D):


void foo(Fun)(Fun bar)
if (isSomeFunction!Fun)   // your constraint that bar is a 
function

{
// how to get your R and A types, if you need them:
alias R = ReturnType!bar;
alias A = Parameters!bar;

alias type = Fun;
pragma(msg, type);

// do some magic
}


Allowing "fall through" of attributes

2016-07-19 Thread Rufus Smith via Digitalmars-d-learn
I have some functions that take other functions. I would like the 
attributes to be able to "fall" through so I get overload like 
behavior. I only care that I am passing a function, not if it is 
shared, extern(C), pure, @nogc, etc.


void foo(R, A...)(R function(A) bar)
{
   alias type = typeof(bar);
   pragma(msg, type);
   // does magic with bar
}

foo never uses the attributes of bar explicitly. It uses type to 
instantiate other functions like bar. I have to create a foo for 
each attribute combination, which is not worth while. The code 
seems to break only for extern, the best I can tell, most 
attributes do pass through. But type does not contain these 
attributes.