Thread overview
Adding pure to a function type
Oct 26, 2017
Adam D. Ruppe
Oct 26, 2017
jmh530
Oct 26, 2017
jmh530
Oct 26, 2017
jmh530
October 26, 2017
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
October 26, 2017
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.
October 26, 2017
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
October 26, 2017
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_)
October 26, 2017
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));
}
October 26, 2017
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
October 26, 2017
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_).