June 11, 2013
On Tuesday, 11 June 2013 at 07:00:29 UTC, Jacob Carlborg wrote:
> This was brought up in the thread reviewing std.serialization:
>
> http://forum.dlang.org/thread/adyanbsdsxsfdpvoozne@forum.dlang.org
>
> Currently we haven't started to use UDA's in Phobos or druntime yet (as far as I know). I would like to start a discussion about putting out some guidelines for using UDA's in Phobos/druntime.
>
> I've created a small module that handles UDA's:
>
> https://github.com/jacob-carlborg/orange/blob/master/orange/core/Attribute.d
>
> The idea is to have a kind of meta UDA called "attribute". This attribute needs to be attached to all structs, enums and so on that is to be used as an attribute.
>
> The module provides a template (getAttributes) to get, by default, only those values attached to a given symbol that is an attribute. That is, marked with the "attribute" attribute.
>
> So my suggestion for guidelines are:
>
> * Only types with the "attribute" UDA is to be used as attributes
> * In general, don't use primitive values as a UDA
>
> Don't use this
>
> @(3) int a;
>
> Use this:
>
> @attribute struct foo { int b; }
>
> @foo(3) int a;
>
> * A user defined type marked with "attribute" should not be used for something else than an UDA
>
> * All attributes use camel case names
>
> If we agree on this and that we need a module like the one above I think it should be added to druntime. The reason for that is that we most likely want to use UDA's in druntime and not only in Phobos. Example, if we ever get std.serialization into Phobos we would want to mark Thread and similar structs/classes as "nonSerialized".
>
> Thoughts?

I agree that attributes should have types - that way it's easily recognizable what are they for in code. "Anonymous" attributes seem to me to be sort of like "you can throw ANYTHING in c++" feature - it's there, but probably without a sane use case.
Could you explain to me what's the benefit of the @attribute convention you introduce? It seems non-obvious to me.
June 11, 2013
On Tuesday, June 11, 2013 16:48:13 Idan Arye wrote:
> Camel case has two versions - and I suggest to use the one that starts with capital

The term pascal case is frequently used when referring to the variant of camelcase which starts with a capital letter.

- Jonathan M Davis
June 11, 2013
On 2013-06-11 18:12, QAston wrote:

> I agree that attributes should have types - that way it's easily
> recognizable what are they for in code. "Anonymous" attributes seem to
> me to be sort of like "you can throw ANYTHING in c++" feature - it's
> there, but probably without a sane use case.
> Could you explain to me what's the benefit of the @attribute convention
> you introduce? It seems non-obvious to me.

It shows the intent of the type. D both have a keywords to indicate an interface and an abstract class. In C++ interfaces and abstract classes are possible as well, but there's no real way to tell that a given class is actually supposed to be used as an interface.

I was kind of disappointed with the way D implemented UDA's. Just dump any value/type to a symbol.

-- 
/Jacob Carlborg
June 11, 2013
On Tuesday, 11 June 2013 at 20:31:22 UTC, Jacob Carlborg wrote:
> On 2013-06-11 18:12, QAston wrote:
>
>> I agree that attributes should have types - that way it's easily
>> recognizable what are they for in code. "Anonymous" attributes seem to
>> me to be sort of like "you can throw ANYTHING in c++" feature - it's
>> there, but probably without a sane use case.
>> Could you explain to me what's the benefit of the @attribute convention
>> you introduce? It seems non-obvious to me.
>
> It shows the intent of the type. D both have a keywords to indicate an interface and an abstract class. In C++ interfaces and abstract classes are possible as well, but there's no real way to tell that a given class is actually supposed to be used as an interface.
>
> I was kind of disappointed with the way D implemented UDA's. Just dump any value/type to a symbol.

Ok, i see the point now, thanks :). Maybe it'd be worth to enforce that convention on a language level, let's say: only types with @attribute can be used as UDA. One reason for making that restriction is that when there's more than a one way of doing something people will do that using all the ways possible. This may be a problem to code which uses many libraries simultanously - your utility functions will not interoperate with UDAs made by someone else.

BTW I've just found one use case for anonymous UDA:
@(Enum.Entry) is verbose, the question is: "Is it useful enough to keep it, or maybe having single convention is better?"
Certainly, there's no need to have arbitrary types in attributes like
@UnawareClass because you can do @TakeUnaware!(UnawareClass) instead.

The other way around would be to operate on @SerializationAttribute specific to the lib so you can fetch only the attributes you're interested in easily.
June 12, 2013
On Tuesday, 11 June 2013 at 21:04:40 UTC, QAston wrote:
> The other way around would be to operate on @SerializationAttribute specific to the lib so you can fetch only the attributes you're interested in easily.

How about passing template arguments to `@attribute` to determine what libraries the UDA it declares belong to?

Here is an example implementation: https://gist.github.com/someboddy/5762072
June 12, 2013
On 2013-06-11 23:04, QAston wrote:

> Ok, i see the point now, thanks :). Maybe it'd be worth to enforce that
> convention on a language level, let's say: only types with @attribute
> can be used as UDA. One reason for making that restriction is that when
> there's more than a one way of doing something people will do that using
> all the ways possible. This may be a problem to code which uses many
> libraries simultanously - your utility functions will not interoperate
> with UDAs made by someone else.

Yes, I would like to have the language enforce this. My utility function fetches by default types that are marked with @attribute. You can add flag when calling the function to fetch all UDA's.

> BTW I've just found one use case for anonymous UDA:
> @(Enum.Entry) is verbose, the question is: "Is it useful enough to keep
> it, or maybe having single convention is better?"

Is it possible to attach a UDA to an enum member? Or is it possible to figure out that it's an enum member and check if the enum itself has @attribute attached to it?

-- 
/Jacob Carlborg
June 12, 2013
On Tuesday, 11 June 2013 at 07:36:44 UTC, Walter Bright wrote:
> On 6/11/2013 12:00 AM, Jacob Carlborg wrote:
>> Thoughts?
>
> I'd like to see more use of UDAs in non-Phobos code so we can figure out best practices from experience before putting it into Phobos, where we'll be stuck with any bad decisions.

That sound good, but the complete opposite have been done every single time. That raise the question of consistency.
June 12, 2013
On 6/11/13, Jacob Carlborg <doob@me.com> wrote:
> I was kind of disappointed with the way D implemented UDA's. Just dump any value/type to a symbol.

But without this you lose the ability to customize. I don't like just "tagging" something, I like D's ability where you can actually customize the UDA, for example:

-----
import std.typetuple;

struct Server
{
    string url;
}

struct Config
{
    @(Server("http://foo.bar")) string name;
    @(Server("http://doo.bar")) string[] items;
}

template GetAttributes(T...) if (T.length == 1)
{
    alias GetAttributes = TypeTuple!(__traits(getAttributes, T[0]));
}

void main()
{
    Config config;

    alias attribs = GetAttributes!(config.name);

    static if (attribs.length && is(typeof(attribs[0]) == test.Server))
    {
        pragma(msg, attribs[0]);
    }
}
-----

Thanks to CTFE we can tag a field with a struct that may have any state. All you have to do in the library code is to first check if any of the attributes is an "attribute type (a struct of some sort)" that you recognize, and then read its state.
June 12, 2013
On Wednesday, 12 June 2013 at 12:29:53 UTC, Andrej Mitrovic wrote:
> On 6/11/13, Jacob Carlborg <doob@me.com> wrote:
>> I was kind of disappointed with the way D implemented UDA's. Just dump
>> any value/type to a symbol.
>
> But without this you lose the ability to customize. I don't like just
> "tagging" something, I like D's ability where you can actually
> customize the UDA, for example:
>

Both are 100% orthogonal
June 12, 2013
On Wednesday, 12 June 2013 at 00:42:24 UTC, Idan Arye wrote:
> How about passing template arguments to `@attribute` to determine what libraries the UDA it declares belong to?
>
> Here is an example implementation: https://gist.github.com/someboddy/5762072

Yes, I think something like this solves interoperation issues.