November 08, 2012 Re: UDAs - Restrict to User Defined Types? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Thursday, 8 November 2012 at 13:19:29 UTC, Jacob Carlborg wrote: > That syntax looks a bit backwards to me. What if I want to annotate the attribute. Sorry, I could not resist: http://cdn.memegenerator.net/instances/400x/29863604.jpg David |
November 08, 2012 Re: UDAs - Restrict to User Defined Types? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Thursday, 8 November 2012 at 13:19:29 UTC, Jacob Carlborg wrote:
> On 2012-11-08 11:56, simendsjo wrote:
>
>> Or
>> struct @foo {}
>> interface @foo {}
>> enum @foo {0
>> etc
>
> That syntax looks a bit backwards to me. What if I want to annotate the attribute.
>
> @serializable struct @foo {}
>
> Looks a bit confusing which is the name of the attribute and the which is the attached annotation.
>
> Vs
>
> @serializable @attribute struct foo {}
>
> No confusion here, "foo" is the name of the attribute, the rest is attached annotations.
I guess it depends. I find it easier to see that it's an attribute, especially when you annotate it. But it's harder to grep for.
Is foo an attribute or not?
@serializable
@xmlRoot
@attribute
@displayName("foo")
struct foo {}
Is foo an attribute or not?
@serializable
@xmlRoot
@displayName("foo")
struct @foo {}
|
November 08, 2012 Re: UDAs - Restrict to User Defined Types? | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | On 2012-11-08 17:26, David Nadlinger wrote: > Sorry, I could not resist: > http://cdn.memegenerator.net/instances/400x/29863604.jpg Hehe, exactly :) -- /Jacob Carlborg |
November 08, 2012 Re: UDAs - Restrict to User Defined Types? | ||||
---|---|---|---|---|
| ||||
Posted in reply to simendsjo | On 2012-11-08 17:53, simendsjo wrote: > I guess it depends. I find it easier to see that it's an attribute, > especially when you annotate it. But it's harder to grep for. > > Is foo an attribute or not? > @serializable > @xmlRoot > @attribute > @displayName("foo") > struct foo {} > > Is foo an attribute or not? > @serializable > @xmlRoot > @displayName("foo") > struct @foo {} > I don't know really. In that bottom example, the struct declartion almost disappears among all the attributes. -- /Jacob Carlborg |
November 08, 2012 Re: UDAs - Restrict to User Defined Types? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Thursday, 8 November 2012 at 17:20:39 UTC, Jacob Carlborg wrote:
> On 2012-11-08 17:53, simendsjo wrote:
>
>> I guess it depends. I find it easier to see that it's an attribute,
>> especially when you annotate it. But it's harder to grep for.
>>
>> Is foo an attribute or not?
>> @serializable
>> @xmlRoot
>> @attribute
>> @displayName("foo")
>> struct foo {}
>>
>> Is foo an attribute or not?
>> @serializable
>> @xmlRoot
>> @displayName("foo")
>> struct @foo {}
>>
>
> I don't know really. In that bottom example, the struct declartion almost disappears among all the attributes.
Yeah.. But at least you'll always know where to look.
@[serializable, xmlRoot, attribute, displayName("foo")]
struct foo {}
@[serializable, xmlRoot, displayName("foo")]
struct @foo {}
but attribute could be required as the last type, and on a line of it's own, giving:
@[serializable, xmlRoot, displayName("foo")]
@attribute
struct foo {}
|
November 08, 2012 Re: UDAs - Restrict to User Defined Types? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | 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 |
November 09, 2012 Re: UDAs - Restrict to User Defined Types? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Thu, 08 Nov 2012 10:05:30 +0100
Jacob Carlborg <doob@me.com> wrote:
>
> I think we should only allow user defined types marked with @attribute, i.e.
>
> @attribute struct foo {}
> @attribute class foo {}
> @attribute interface foo {}
> @attribute enum foo {}
>
> And so on.
>
I completely agree. I really hate when languages "play it loose" and leave things up to arbitrary convention. It's like duck/structural typing: the *one* thing I hate about D ranges is that they don't force you to explicitly say "Yes, I *intend* this to be an InputRange" (what are we, Go users?). I don't want to see the same unhelpful sloppiness here.
|
November 09, 2012 Re: UDAs - Restrict to User Defined Types? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | On Thu, Nov 08, 2012 at 10:45:05PM -0500, Nick Sabalausky wrote: > On Thu, 08 Nov 2012 10:05:30 +0100 > Jacob Carlborg <doob@me.com> wrote: > > > > I think we should only allow user defined types marked with @attribute, i.e. > > > > @attribute struct foo {} > > @attribute class foo {} > > @attribute interface foo {} > > @attribute enum foo {} > > > > And so on. > > > > I completely agree. I really hate when languages "play it loose" and leave things up to arbitrary convention. It's like duck/structural typing: the *one* thing I hate about D ranges is that they don't force you to explicitly say "Yes, I *intend* this to be an InputRange" (what are we, Go users?). I don't want to see the same unhelpful sloppiness here. Actually, I just thought of a solution to the whole duck-typing range thing: struct MyRange { // Self-documenting: this struct is intended to be a // range. static assert(isInputRange!MyRange, "Dude, your struct isn't a range!"); // asserts @property bool empty() { ... } @property auto front() { ... } int popFront() { ... } } struct WhatItShouldBe { // Junior programmer modifies the function signatures // below and the compiler gives him a scolding. static assert(isInputRange!WhatItShouldBe, "Dude, you just broke my range!"); // passes @property bool empty() { ... } @property auto front() { ... } void popFront() { ... } } void main() { auto needle = "abc"; auto x = find(WhatItShouldBe(), needle); } T -- I see that you JS got Bach. |
November 09, 2012 Re: UDAs - Restrict to User Defined Types? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | On Friday, 9 November 2012 at 03:45:11 UTC, Nick Sabalausky wrote:
> the *one* thing I hate about D ranges is that they don't force you to explicitly say "Yes, I *intend* this to be an InputRange" (what are we, Go users?).
Just a note, of course it still wouldn't *force*, but maybe it'd be a good habit to start writing this:
struct myrange {...}
static assert(isInputRange!myrange);
It'd be a simple way to get a check at the point of declaration and to document your intent.
Interestingly, we could also do this if the attributes could run through a template:
[check!isInputRange] struct myrange{}
@attribute template check(something, Decl) {
static assert(something!Decl);
alias check = Decl;
}
Same thing, diff syntax.
|
November 09, 2012 Re: UDAs - Restrict to User Defined Types? | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Thu, 8 Nov 2012 20:17:24 -0800 "H. S. Teoh" <hsteoh@quickfur.ath.cx> wrote: > > Actually, I just thought of a solution to the whole duck-typing range thing: > > struct MyRange { > // Self-documenting: this struct is intended to be a > // range. > static assert(isInputRange!MyRange, > "Dude, your struct isn't a range!"); // > asserts > > On Fri, 09 Nov 2012 05:18:59 +0100 "Adam D. Ruppe" <destructionator@gmail.com> wrote: > > Just a note, of course it still wouldn't *force*, but maybe it'd be a good habit to start writing this: > > struct myrange {...} > static assert(isInputRange!myrange); > Those are only half-solutions as they only prevent false-negatives, not false-positives. Plus, there's nothing to prevent people from forgetting to do it in the first place. I outlined and implemented a proof-of-concept for a full solution middle of last year: http://www.semitwist.com/articles/EfficientAndFlexible/MultiplePages/Page5/ The basic gist (and there's definitely still room for plenty of improvement): // The General Tool: string declareInterface(string interfaceName, string thisType) { return ` // Announce what interface this implements. static enum _this_implements_interface_`~interfaceName~`_ = true; // Verify this actually does implement the interface static assert( is`~interfaceName~`!(`~thisType~`), "This type fails to implement `~interfaceName~`" ); `; } // Sample usage: template isFoo(T) { immutable bool isFoo = __traits(compiles, (){ T t; static assert(T._this_implements_interface_Foo_); t.fooNum = 5; int x = t.fooFunc(""); // Check everything else here }); } struct MyFoo { // Can probably be more DRY with fancy trickery mixin(declareInterface("Foo", "MyFoo")); int fooNum; int fooFunc(string a) {...} } What I'd really like to see is a way to implement declareInterface so that the isFoo is replaced by an ordinary "interface Foo {...}", which MyFoo's members are automatically checked against. I suspect that should be possible with some fancy metaprogramming-fu. |
Copyright © 1999-2021 by the D Language Foundation