On Wednesday, 7 November 2012 at 23:18:41 UTC, Walter Bright
wrote:
Started a new thread on this.
On 11/7/2012 3:05 AM, Leandro Lucarella wrote:
> OK, that's another thing. And maybe a reason for listening to
people having
> more experience with UDAs than you.
>
> For me the analogy with Exceptions is pretty good. The issues
an conveniences
> of throwing anything or annotating a symbol with anything
instead of just
> type are pretty much the same. I only see functions making
sense to be accepted
> as annotations too (that's what Python do with annotations,
@annotation symbol
> is the same as symbol = annotation(symbol), but is quite a
different language).
There's another aspect to this.
D's UDAs are a purely compile time system, attaching arbitrary
metadata to specific symbols. The other UDA systems I'm aware
of appear to be runtime systems.
This implies the use cases will be different - how, I don't
really know. But I don't know of any other compile time UDA
system. Experience with runtime systems may not be as
applicable.
Another interesting data point is CTFE. C++11 has CTFE, but it
was deliberately crippled and burdened with "constexpr". From
what I read, this was out of fear that it would turn out to be
an overused and overabused feature. Of course, this turned out
to be a large error.
One last thing. Sure, string attributes can (and surely would
be) used for different purposes in different libraries. The
presumption is that this would cause a conflict. But would it?
There are two aspects to a UDA - the attribute itself, and the
symbol it is attached to. In order to get the UDA for a symbol,
one has to look up the symbol. There isn't a global repository
of symbols in D. You'd have to say "I want to look in module X
for symbols." Why would you look in module X for an attribute
that you have no reason to believe applies to symbols from X?
How would an attribute for module X's symbols leak out of X on
their own?
It's not quite analogous to exceptions, because arbitrary
exceptions thrown from module X can flow through your code even
though you have no idea module X even exists.
In module sql.d:
/// For every field marked ["serialize"], add to table
void saveToDatabase(T)(DBConnection db, T model);
In module json.d:
/// For every field marked ["serialize"], add to JSON object
string jsonSerialize(T)(T obj);
In module userinfo.d:
["dbmodel"]
struct UserModel {
["serialize"] string username;
// What do you do if you want this in the database, but
not the JSON?
string password;
["serialize"] Content ownedContentOrWhateverThisWebsiteIs;
}
The only solution to this question is to differentiate
"db_serialize" and "json_serialize"; looks a lot like C, doesn't
it?
My suggested soluion: @annotation (with [] UDA syntax):
module sql;
@annotation enum model;
@annotation enum serialize;
module json;
@annotation enum serialize;
module userinfo;
import sql, json;
[sql.model]
struct UserModel {
[sql.serialize, json.serialize] string username;
[sql.serialize] string password;
[sql.serialize, json.serialize] Content content;
}
My thoughts,
NMS