January 18, 2014
On Fri, Jan 17, 2014 at 10:02:44PM -0500, Steven Schveighoffer wrote:
> On Fri, 17 Jan 2014 21:50:07 -0500, Stanislav Blinov <stanislav.blinov@gmail.com> wrote:
> 
> >On Saturday, 18 January 2014 at 02:38:28 UTC, H. S. Teoh wrote:
> >
> >>What's wrong with just letting the compiler infer the maximal function attributes?
> >
> >...
> >
> >>Sadly, this only works for template functions currently -- so I still had to annotate the various method()'s by hand, but if you were to turn them into template functions too, their attributes will also be inferred automatically.
> >
> >Oh, I see now where it went the wrong way. From my own example, of course :)
> >
> >Surely I was meaning:
> >
> >class Careful(T) {
> >//...
> >   void thisIsSoPolymorphic() nothrow(isNoThrow!(T.foo)) { ... }
> >//...
> >}
> >
> >Something to that extent. So that yes, the function itself is not a template.
> 
> I was about to respond with a similar point, but it seems you are understanding now how the nothrow inference works :)
> 
> I can't think of a correct way to do this without repeating code, since it has to be polymorphic (and therefore not a template), nothrow inference only works on templates.

See https://d.puremagic.com/issues/show_bug.cgi?id=10329 and the associated pull, which has just been merged. I haven't tested it myself yet, but it would appear that methods inside template classes should now have their methods' attributes inferred too?

If so, then you can just take out the nothrow clause and it should work? (But since I haven't tested this yet I could be wrong.)


> The idea to be able to attach attributes/annotations based on compile-time introspection would be a worthy addition to the language IMO, but I really don't like the syntax you have outlined (I see you don't like it either). Especially if you have to do all the attributes this way.
> 
> I think a "use the attributes of X" would be a general enough tool.
> 
> Something like:
> 
>  void thisIsSoPolymorphic() attrOf(T.foo)
[...]

Hmm. Would functionAttributes and SetFunctionAttributes in std.traits help somehow? Not sure how you might actually use them to declare methods with desired attributes, though. But maybe there's a way.


T

-- 
Always remember that you are unique. Just like everybody else. -- despair.com
January 18, 2014
On Saturday, 18 January 2014 at 03:02:45 UTC, Steven Schveighoffer wrote:

> I was about to respond with a similar point, but it seems you are understanding now how the nothrow inference works :)

O:)

> I can't think of a correct way to do this without repeating code, since it has to be polymorphic (and therefore not a template), nothrow inference only works on templates.
>
> The idea to be able to attach attributes/annotations based on compile-time introspection would be a worthy addition to the language IMO, but I really don't like the syntax you have outlined (I see you don't like it either).

No, I actually quite like that C++ syntax, although AFAIK it's only "special" in that one particular occasion. I was mentioning that syntax doesn't matter because I wanted to make sure I'm not pushing any C++ features here, just making a point about a nice usability feature :)

> Especially if you have to do all the attributes this way.

> I think a "use the attributes of X" would be a general enough tool.
>
> Something like:
>
>  void thisIsSoPolymorphic() attrOf(T.foo)

And here is where I would disagree. Fine-grained control over each attribute is more important. For example, the function may be always nothrow (say I handle all the exceptions in the world or assert(0) on what's left; D helpfully doesn't consider assert(0) as throwing :) ), but it may be conditionally pure or safe.
January 18, 2014
On Fri, 17 Jan 2014 22:21:15 -0500, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:

> On Fri, Jan 17, 2014 at 10:02:44PM -0500, Steven Schveighoffer wrote:
>> On Fri, 17 Jan 2014 21:50:07 -0500, Stanislav Blinov
>> <stanislav.blinov@gmail.com> wrote:
>>
>> >On Saturday, 18 January 2014 at 02:38:28 UTC, H. S. Teoh wrote:
>> >
>> >>What's wrong with just letting the compiler infer the maximal function
>> >>attributes?
>> >
>> >...
>> >
>> >>Sadly, this only works for template functions currently -- so I still
>> >>had to annotate the various method()'s by hand, but if you were to  
>> turn
>> >>them into template functions too, their attributes will also be  
>> inferred
>> >>automatically.
>> >
>> >Oh, I see now where it went the wrong way. From my own example, of
>> >course :)
>> >
>> >Surely I was meaning:
>> >
>> >class Careful(T) {
>> >//...
>> >   void thisIsSoPolymorphic() nothrow(isNoThrow!(T.foo)) { ... }
>> >//...
>> >}
>> >
>> >Something to that extent. So that yes, the function itself is not
>> >a template.
>>
>> I was about to respond with a similar point, but it seems you are
>> understanding now how the nothrow inference works :)
>>
>> I can't think of a correct way to do this without repeating code,
>> since it has to be polymorphic (and therefore not a template),
>> nothrow inference only works on templates.
>
> See https://d.puremagic.com/issues/show_bug.cgi?id=10329 and the
> associated pull, which has just been merged. I haven't tested it myself
> yet, but it would appear that methods inside template classes should now
> have their methods' attributes inferred too?

Hm... how does that work on a virtual function? You may not know the body.

It does seem like a good solution for most cases.

>> The idea to be able to attach attributes/annotations based on
>> compile-time introspection would be a worthy addition to the
>> language IMO, but I really don't like the syntax you have outlined
>> (I see you don't like it either). Especially if you have to do all
>> the attributes this way.
>>
>> I think a "use the attributes of X" would be a general enough tool.
>>
>> Something like:
>>
>>  void thisIsSoPolymorphic() attrOf(T.foo)
> [...]
>
> Hmm. Would functionAttributes and SetFunctionAttributes in std.traits
> help somehow? Not sure how you might actually use them to declare
> methods with desired attributes, though. But maybe there's a way.

Not sure, it looks like SetFunctionAttributes only can be used to construct types, not declare functions.

-Steve
January 18, 2014
On Fri, 17 Jan 2014 22:25:11 -0500, Stanislav Blinov <stanislav.blinov@gmail.com> wrote:

> On Saturday, 18 January 2014 at 03:02:45 UTC, Steven Schveighoffer wrote:

>> I think a "use the attributes of X" would be a general enough tool.
>>
>> Something like:
>>
>>  void thisIsSoPolymorphic() attrOf(T.foo)
>
> And here is where I would disagree. Fine-grained control over each attribute is more important. For example, the function may be always nothrow (say I handle all the exceptions in the world or assert(0) on what's left; D helpfully doesn't consider assert(0) as throwing :) ), but it may be conditionally pure or safe.

void thisIsSoPolymorphic() attrOf(T.foo) nothrow

I would assume, we could come up with ways to mask out attributes you want to set specifically. For example if you always want it NOT to be nothrow, you could do something like:

void thisIsSoPolymorphic() attrOf(withoutNothrow!(T.foo))

-Steve
January 18, 2014
On Saturday, 18 January 2014 at 03:22:43 UTC, H. S. Teoh wrote:
> On Fri, Jan 17, 2014 at 10:02:44PM -0500, Steven Schveighoffer wrote:

> See https://d.puremagic.com/issues/show_bug.cgi?id=10329

> If so, then you can just take out the nothrow clause and it should work?
> (But since I haven't tested this yet I could be wrong.)

Hmm... It certainly *looks* that way, but I don't have a local pull of the compiler, so can't test either. But if it's true, that's great!


> Hmm. Would functionAttributes and SetFunctionAttributes in std.traits
> help somehow? Not sure how you might actually use them to declare
> methods with desired attributes, though. But maybe there's a way.

functionAttributes can be used for inference (see isNoThrow in my first post). But alas, currently attributes can't be mixed-in or otherwise conditionally specified (without resorting to static if), at least I don't know one, what prompted me to start this topic in the first place.
January 18, 2014
On 2014-01-18 04:02, Steven Schveighoffer wrote:

> I think a "use the attributes of X" would be a general enough tool.
>
> Something like:
>
>   void thisIsSoPolymorphic() attrOf(T.foo)

Yet another case for AST macros:

class Careful (T)
{
    void thisIsSoPolymporphic () @inferAttributes(T.foo) { }
}

macro inferAttributes (Context context, Ast!(Symbol) symbol, Declaration decl)
{
    foreach (attr ; symbol.attributes)
        decl.attributes ~= attr;

    return decl;
}

-- 
/Jacob Carlborg
January 18, 2014
On 01/18/2014 03:50 AM, Stanislav Blinov wrote:
>>
>
> Oh, I see now where it went the wrong way. From my own example, of
> course :)
>
> Surely I was meaning:
>
> class Careful(T) {
> //...
>    void thisIsSoPolymorphic() nothrow(isNoThrow!(T.foo)) { ... }
> //...
> }
>
> Something to that extent. So that yes, the function itself is not a
> template.

Well, but it will be annotated nothrow anyway if possible. Inference is not actually limited in the implied way.

In case you _really_ want to be explicit about this (and you seem not to), the general problem precluding a nice library implementation is that built-in attributes cannot be aliased.

You can always use a string mixin though:

mixin(`void thisIsSoPolymorphic()`~(isNoThrow!(T.foo)?:"nothrow":"")~q{{
    ...
}});

This easily scales to all attributes you may find interesting:

mixin(`void thisIsSoPolymorphic()`~stringOfAttributes!(T.foo)~q{{
    ...
}});

1 2
Next ›   Last »