www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Adding pure to a function type

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
So I'm trying to add "pure" to a function of which type is otherwise 
deduced by the compiler:

package  property pure
T lazilyInitializedConstant(T, alias outOfBandValue, alias initializer)()
if (is(Unqual!T : T))
{
     static T impl()
     {
         ...
     }
     mixin("alias Fun = " ~ typeof(&impl).stringof ~ " pure;");
     return (cast(Fun) &impl)();
}

The type of impl depends on T, and when converted to string is something 
like e.g. "immutable(ulong) function() nothrow  nogc  system".

I tried "alias Fun = pure typeof(&impl);" which compiled (!), but didn't 
work - Fun is not actually a pure type.

So I went with the hammer that will fix anything - a string mixin. Ideas 
for a nicer solution?


Andrei
Oct 26
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 26 October 2017 at 15:04:52 UTC, Andrei Alexandrescu 
wrote:
 So I went with the hammer that will fix anything - a string 
 mixin. Ideas for a nicer solution?
The stdlib has: SetFunctionAttributes in std.traits http://dpldocs.info/experimental-docs/std.traits.SetFunctionAttributes.1.html Its implementation is string mixin, but at least on the user side it looks less hideous.
Oct 26
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/26/2017 11:10 AM, Adam D. Ruppe wrote:
 On Thursday, 26 October 2017 at 15:04:52 UTC, Andrei Alexandrescu wrote:
 So I went with the hammer that will fix anything - a string mixin. 
 Ideas for a nicer solution?
The stdlib has: SetFunctionAttributes in std.traits http://dpldocs.info/experimental-docs/std.traits.SetFunctionAttributes.1.html Its implementation is string mixin, but at least on the user side it looks less hideous.
s/less hideous/even more awesome/ No need to be testy :o). I noticed there's no way to say "just leave linkage as is". I tried SetFunctionAttributes!(typeof(&impl), null, FunctionAttribute.pure_) and SetFunctionAttributes!(typeof(&impl), "", FunctionAttribute.pure_) but neither worked. Should I file a bug? Andrei
Oct 26
parent reply jmh530 <john.michael.hall gmail.com> writes:
On Thursday, 26 October 2017 at 15:47:03 UTC, Andrei Alexandrescu 
wrote:
 s/less hideous/even more awesome/

 No need to be testy :o).

 I noticed there's no way to say "just leave linkage as is". I 
 tried SetFunctionAttributes!(typeof(&impl), null, 
 FunctionAttribute.pure_) and 
 SetFunctionAttributes!(typeof(&impl), "", 
 FunctionAttribute.pure_) but neither worked. Should I file a 
 bug?


 Andrei
How about: SetFunctionAttributes!(typeof(&impl), functionLinkage!(&impl), FunctionAttribute.pure_)
Oct 26
parent reply jmh530 <john.michael.hall gmail.com> writes:
On Thursday, 26 October 2017 at 16:06:28 UTC, jmh530 wrote:
 On Thursday, 26 October 2017 at 15:47:03 UTC, Andrei 
 Alexandrescu wrote:
 s/less hideous/even more awesome/

 No need to be testy :o).

 I noticed there's no way to say "just leave linkage as is". I 
 tried SetFunctionAttributes!(typeof(&impl), null, 
 FunctionAttribute.pure_) and 
 SetFunctionAttributes!(typeof(&impl), "", 
 FunctionAttribute.pure_) but neither worked. Should I file a 
 bug?


 Andrei
How about: SetFunctionAttributes!(typeof(&impl), functionLinkage!(&impl), FunctionAttribute.pure_)
Or we can just add in additional overloads like: template SetFunctionAttributes(T, uint attrs) if (isFunctionPointer!T || isDelegate!T) { alias SetFunctionAttributes = FunctionTypeOf!(SetFunctionAttributes!(T, functionLinkage!T, attrs)); } template SetFunctionAttributes(T, uint attrs) if (is(T == function)) { alias SetFunctionAttributes = FunctionTypeOf!(SetFunctionAttributes!(T*, attrs)); } template SetFunctionAttributes(T, string linkage) if (isFunctionPointer!T || isDelegate!T) { alias SetFunctionAttributes = FunctionTypeOf!(SetFunctionAttributes!(T, linkage, functionAttributes!T)); } template SetFunctionAttributes(T, string linkage) if (is(T == function)) { alias SetFunctionAttributes = FunctionTypeOf!(SetFunctionAttributes!(T*, linkage)); }
Oct 26
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/26/2017 12:14 PM, jmh530 wrote:
 On Thursday, 26 October 2017 at 16:06:28 UTC, jmh530 wrote:
 On Thursday, 26 October 2017 at 15:47:03 UTC, Andrei Alexandrescu wrote:
 s/less hideous/even more awesome/

 No need to be testy :o).

 I noticed there's no way to say "just leave linkage as is". I tried 
 SetFunctionAttributes!(typeof(&impl), null, FunctionAttribute.pure_) 
 and SetFunctionAttributes!(typeof(&impl), "", 
 FunctionAttribute.pure_) but neither worked. Should I file a bug?


 Andrei
How about: SetFunctionAttributes!(typeof(&impl), functionLinkage!(&impl), FunctionAttribute.pure_)
Or we can just add in additional overloads like: template SetFunctionAttributes(T, uint attrs)     if (isFunctionPointer!T || isDelegate!T) {     alias SetFunctionAttributes = FunctionTypeOf!(SetFunctionAttributes!(T, functionLinkage!T, attrs)); } template SetFunctionAttributes(T, uint attrs)     if (is(T == function)) {     alias SetFunctionAttributes = FunctionTypeOf!(SetFunctionAttributes!(T*, attrs)); } template SetFunctionAttributes(T, string linkage)     if (isFunctionPointer!T || isDelegate!T) {     alias SetFunctionAttributes = FunctionTypeOf!(SetFunctionAttributes!(T, linkage, functionAttributes!T)); } template SetFunctionAttributes(T, string linkage)     if (is(T == function)) {     alias SetFunctionAttributes = FunctionTypeOf!(SetFunctionAttributes!(T*, linkage)); }
One additional thing I noted is that I wanted to add attributes, not set them. I'd like some simpler primitives like AddPure, RemovePure etc. BTW the PR is https://github.com/dlang/phobos/pull/5470. -- Andrei
Oct 26
parent jmh530 <john.michael.hall gmail.com> writes:
On Thursday, 26 October 2017 at 19:08:56 UTC, Andrei Alexandrescu 
wrote:
 One additional thing I noted is that I wanted to add 
 attributes, not set them. I'd like some simpler primitives like 
 AddPure, RemovePure etc. BTW the PR is 
 https://github.com/dlang/phobos/pull/5470. -- Andrei
My above code could be easily adapted for adding attributes in the general case. The doc unittest for SetFunctionAttributes has an assumePure that shows how to add an attribute (though I'm not sure on removing). While I think that it makes sense to add an AddFunctionAttributes/RemoveFunctionAttributes that match the functionality of SetFunctionAttributes, it's probably more convenient to also add an overload with a string template parameter, so AddPure!T would just be AddFunctionAttributes!(T, "pure") instead of AddFunctionAttributes!(T, FunctionAttribute.pure_).
Oct 26