www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Proposal: Definition of -attributes

reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
In the "Function calls" thread the question of "which attributes should 
be in the  -namespace" has again come up.


Problem:
Currently, there doesn't seem to be any clear definition of which 
attributes should be prefixed with   and which shouldn't.  New 
attributes get an  , while already existing attributes don't, and it all 
seems a bit arbitrary.  Then again, we probably don't want *all* 
attributes to be written with  , as that would just make code look messy:

      safe  nothrow  private  property int foo() { ... }


Solution (?):
I therefore propose the following definition of  -namespace attributes:

     The  -attributes of a function only place compile-time
     constraints on the body of that function.

Specifically, this means that the  -attributes of a function do not 
place constraints on calling code, change the syntax of calling code, 
nor change the visibility of the function.

The above definition means that the following will be  -attributes:

      safe,  trusted,  unsafe
      nothrow,  pure

The following, on the other hand, will be normal keywords:

     private, protected, public
     deprecated, disable
     property

I realise that a major problem with the proposal is that it severely 
limits the possibility of later having user-defined annotations in the 
 -namespace as well.  But I am not convinced this is a good idea anyway.

I'd also suggest the convention that  -attributes are written after the 
function signature, while other attributes are written before:

     private property int foo()   safe  nothrow { ... }

Comments?

-Lars
Jan 28 2010
next sibling parent Jason House <jason.james.house gmail.com> writes:
Lars T. Kyllingstad Wrote:

 In the "Function calls" thread the question of "which attributes should 
 be in the  -namespace" has again come up.
 
 
 Problem:
 Currently, there doesn't seem to be any clear definition of which 
 attributes should be prefixed with   and which shouldn't.  New 
 attributes get an  , while already existing attributes don't, and it all 
 seems a bit arbitrary.  Then again, we probably don't want *all* 
 attributes to be written with  , as that would just make code look messy:
 
       safe  nothrow  private  property int foo() { ... }
 
 
 Solution (?):
 I therefore propose the following definition of  -namespace attributes:
 
      The  -attributes of a function only place compile-time
      constraints on the body of that function.
That kills the extensibility of attributes. Users should be able to define attributes that are only used through reflection. It may be best to define a criteria for what constitutes a keyword.
 Specifically, this means that the  -attributes of a function do not 
 place constraints on calling code, change the syntax of calling code, 
 nor change the visibility of the function.
What you list as attributes does effect calling code when the calling code uses certain attributes...
 
 The above definition means that the following will be  -attributes:
 
       safe,  trusted,  unsafe
       nothrow,  pure
 
 The following, on the other hand, will be normal keywords:
 
      private, protected, public
      deprecated, disable
      property
This division seems reasonable to me.
 I realise that a major problem with the proposal is that it severely 
 limits the possibility of later having user-defined annotations in the 
  -namespace as well.  But I am not convinced this is a good idea anyway.
Many of those that wanted attributes in the first place wanted it because of its extensibility.
Jan 28 2010
prev sibling next sibling parent reply Don <nospam nospam.com> writes:
Lars T. Kyllingstad wrote:
 Currently, there doesn't seem to be any clear definition of which 
 attributes should be prefixed with   and which shouldn't.
[snip]
 Solution (?):
 I therefore propose the following definition of  -namespace attributes:
 
     The  -attributes of a function only place compile-time
     constraints on the body of that function.
 
 Specifically, this means that the  -attributes of a function do not 
 place constraints on calling code, change the syntax of calling code, 
 nor change the visibility of the function.
 
 The above definition means that the following will be  -attributes:
 
      safe,  trusted,  unsafe
      nothrow,  pure
unsafe places constraints on calling code: it can't be safe.
 The following, on the other hand, will be normal keywords:
 
     private, protected, public
     deprecated, disable
     property
 
 I realise that a major problem with the proposal is that it severely 
 limits the possibility of later having user-defined annotations in the 
  -namespace as well.  But I am not convinced this is a good idea anyway.
It's hard to come up with a definition which lets private, protected, public remain as keywords. It seems to be almost impossible to come up with a definition which keeps property as an annotation. The simple rule of thumb, "a program which compiles, should still work if all of the annotations are removed" (obviously, excluding metaprogramming code which is checking for annotations) comes close, but fails miserably at property.
Jan 28 2010
parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Don wrote:
 Lars T. Kyllingstad wrote:
 Currently, there doesn't seem to be any clear definition of which 
 attributes should be prefixed with   and which shouldn't.
[snip]
 Solution (?):
 I therefore propose the following definition of  -namespace attributes:

     The  -attributes of a function only place compile-time
     constraints on the body of that function.

 Specifically, this means that the  -attributes of a function do not 
 place constraints on calling code, change the syntax of calling code, 
 nor change the visibility of the function.

 The above definition means that the following will be  -attributes:

      safe,  trusted,  unsafe
      nothrow,  pure
unsafe places constraints on calling code: it can't be safe.
I considered that, but I think of it the other way around: It's safe that places the "can't call unsafe" constraint, and not unsafe that places a "can't be called by safe" constraint. But I agree there's a fair bit of arbitrariness in this as well. :) -Lars
Jan 28 2010
prev sibling next sibling parent reply Leandro Lucarella <llucax gmail.com> writes:
Lars T. Kyllingstad, el 28 de enero a las 09:46 me escribiste:
 In the "Function calls" thread the question of "which attributes
 should be in the  -namespace" has again come up.
 
 Problem:
 Currently, there doesn't seem to be any clear definition of which
 attributes should be prefixed with   and which shouldn't.  New
 attributes get an  , while already existing attributes don't, and it
 all seems a bit arbitrary.  Then again, we probably don't want *all*
 attributes to be written with  , as that would just make code look
 messy:
 
      safe  nothrow  private  property int foo() { ... }
 
 
 Solution (?):
 I therefore propose the following definition of  -namespace attributes:
 
     The  -attributes of a function only place compile-time
     constraints on the body of that function.
 
 Specifically, this means that the  -attributes of a function do not
 place constraints on calling code, change the syntax of calling
 code, nor change the visibility of the function.
 
 The above definition means that the following will be  -attributes:
 
      safe,  trusted,  unsafe
      nothrow,  pure
 
 The following, on the other hand, will be normal keywords:
 
     private, protected, public
     deprecated, disable
     property
 
 I realise that a major problem with the proposal is that it severely
 limits the possibility of later having user-defined annotations in
 the  -namespace as well.  But I am not convinced this is a good idea
 anyway.
It is! Even more, a big reason for introducing attributes was to be able to make them user-defined. I don't like your proposal mostly because of this point (but because is as arbitrary as the current regime, it only adds a mnemonic rule to remember where to put the ). I think all D attributes should have the , if you have a bunch of them, maybe there should be a way to group them, like: (safe nothrow private property) int foo() { ... } But I'm not sure that adds anything to readability. I don't think this is a huge problem, since as somebody already pointed out, you can always group declarations with the same attributes together and type the attribute just once (this is not Java :). -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ----------------------------------------------------------------------
Jan 28 2010
parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Leandro Lucarella wrote:
 Lars T. Kyllingstad, el 28 de enero a las 09:46 me escribiste:
 In the "Function calls" thread the question of "which attributes
 should be in the  -namespace" has again come up.

 Problem:
 Currently, there doesn't seem to be any clear definition of which
 attributes should be prefixed with   and which shouldn't.  New
 attributes get an  , while already existing attributes don't, and it
 all seems a bit arbitrary.  Then again, we probably don't want *all*
 attributes to be written with  , as that would just make code look
 messy:

      safe  nothrow  private  property int foo() { ... }


 Solution (?):
 I therefore propose the following definition of  -namespace attributes:

     The  -attributes of a function only place compile-time
     constraints on the body of that function.

 Specifically, this means that the  -attributes of a function do not
 place constraints on calling code, change the syntax of calling
 code, nor change the visibility of the function.

 The above definition means that the following will be  -attributes:

      safe,  trusted,  unsafe
      nothrow,  pure

 The following, on the other hand, will be normal keywords:

     private, protected, public
     deprecated, disable
     property

 I realise that a major problem with the proposal is that it severely
 limits the possibility of later having user-defined annotations in
 the  -namespace as well.  But I am not convinced this is a good idea
 anyway.
It is! Even more, a big reason for introducing attributes was to be able to make them user-defined.
I may be wrong, but somehow I got the impression that the important thing for Walter & co. was to have a new namespace for attributes, to avoid introducing a bunch of new keywords. Then it makes no sense to use the same namespace for user-defined annotations, as adding new attributes later will be no better than adding keywords -- it will restrict or clash with user-defined annotations.
 I don't like your proposal mostly because of this point (but because is as
 arbitrary as the current regime, it only adds a mnemonic rule to remember
 where to put the  ).
To a certain degree I agree with the latter. It was just the most definite rule I could come up with that includes safe, unsafe, etc. but not private, public, etc. Also it doesn't increase the keyword count -- sure, 'property' and 'disable' become keywords, but 'pure' and 'nothrow' become annotations.
 I think all D attributes should have the  , if you have a bunch of them,
 maybe there should be a way to group them, like:
 
       (safe nothrow private property) int foo() { ... }
 
 But I'm not sure that adds anything to readability. I don't think this is
 a huge problem, since as somebody already pointed out, you can always
 group declarations with the same attributes together and type the
 attribute just once (this is not Java :).
That doesn't look too bad, but if *all* attributes are in the -namespace, then we *really* should keep user-defined annotations out of it. -Lars
Jan 28 2010
parent reply Leandro Lucarella <llucax gmail.com> writes:
Lars T. Kyllingstad, el 28 de enero a las 15:38 me escribiste:
I think all D attributes should have the  , if you have a bunch of them,
maybe there should be a way to group them, like:

      (safe nothrow private property) int foo() { ... }

But I'm not sure that adds anything to readability. I don't think this is
a huge problem, since as somebody already pointed out, you can always
group declarations with the same attributes together and type the
attribute just once (this is not Java :).
That doesn't look too bad, but if *all* attributes are in the -namespace, then we *really* should keep user-defined annotations out of it.
I don't know, maybe you're right. (thinking out loud, what's next can be a load of crap, be warned :) User defined annotation can have namespaces though: import foo; foo.bar f() { // ... } But if foo gets introduced in the future as a language feature, you're doom. Maybe attributes should be always "imported" and be subject to lookup rules just like regular funcions? static import std.attr; // standard import std.safe: trusted; // standard import foo: public; // non-standard std.attr.nothrow trusted public f(); It is a radical change, so I don't expect it to be in D2 of course. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ----------------------------------------------------------------------
Jan 28 2010
parent reply Clemens <eriatarka84 gmail.com> writes:
Leandro Lucarella Wrote:

 Lars T. Kyllingstad, el 28 de enero a las 15:38 me escribiste:
I think all D attributes should have the  , if you have a bunch of them,
maybe there should be a way to group them, like:

      (safe nothrow private property) int foo() { ... }

But I'm not sure that adds anything to readability. I don't think this is
a huge problem, since as somebody already pointed out, you can always
group declarations with the same attributes together and type the
attribute just once (this is not Java :).
That doesn't look too bad, but if *all* attributes are in the -namespace, then we *really* should keep user-defined annotations out of it.
I don't know, maybe you're right. (thinking out loud, what's next can be a load of crap, be warned :)
If and when D gets user-defined attributes, they could have their own namespace: foo or maybe #foo Maybe it's too ugly though, but then the current attribute syntax isn't a thing of beauty to begin with. Clemens
Jan 29 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Clemens:

It's not used, maybe because D tries to not use C syntax with a different semantics. If this constraints get relaxed, then probably we can invent some useful way to use it. Do you have ideas? Bye, bearophile
Jan 29 2010
parent =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= <pelle.mansson gmail.com> writes:
On 01/29/2010 12:13 PM, bearophile wrote:
 Clemens:

It's not used, maybe because D tries to not use C syntax with a different semantics. If this constraints get relaxed, then probably we can invent some useful way to use it. Do you have ideas? Bye, bearophile
Oh it's used! ...for the #line declaration.
Jan 29 2010
prev sibling parent retard <re tard.com.invalid> writes:
Fri, 29 Jan 2010 05:41:00 -0500, Clemens wrote:

 Leandro Lucarella Wrote:
 
 Lars T. Kyllingstad, el 28 de enero a las 15:38 me escribiste:
I think all D attributes should have the  , if you have a bunch of
them, maybe there should be a way to group them, like:

      (safe nothrow private property) int foo() { ... }

But I'm not sure that adds anything to readability. I don't think
this is a huge problem, since as somebody already pointed out, you
can always group declarations with the same attributes together and
type the attribute just once (this is not Java :).
That doesn't look too bad, but if *all* attributes are in the -namespace, then we *really* should keep user-defined annotations out of it.
I don't know, maybe you're right. (thinking out loud, what's next can be a load of crap, be warned :)
If and when D gets user-defined attributes, they could have their own namespace: foo or maybe #foo Maybe it's too ugly though, but then the current attribute syntax isn't a thing of beauty to begin with.
I'm wondering. If I make a tool that parses D sources such as a documentation generator, can I define new annotations freely or are there any rules involved? I could really have use for e.g. unit testing annotations. The compiler should ignore them, however - preferably now and also in the future.
Jan 29 2010
prev sibling next sibling parent reply Jesse Phillips <jessekphillips+D gmail.com> writes:
Lars T. Kyllingstad wrote:

 In the "Function calls" thread the question of "which attributes should 
 be in the  -namespace" has again come up.


 Problem:
 Currently, there doesn't seem to be any clear definition of which 
 attributes should be prefixed with   and which shouldn't.  New 
 attributes get an  , while already existing attributes don't, and it all 
 seems a bit arbitrary.  Then again, we probably don't want *all* 
 attributes to be written with  , as that would just make code look messy:
To me attributes can make the code look uglier and, as pointed out, there there really is no clear seperation. So in my opinion, to keep the code looking clean attributes should only include those for the function, not its parameters. This prevents in, out, ref, const, etc. and allows for safe, property, etc. If a delegate is a parameter than attributes would of course be ok in the parameter since they apply to a function.
Jan 28 2010
parent Leandro Lucarella <llucax gmail.com> writes:
Jesse Phillips, el 28 de enero a las 15:39 me escribiste:
 Lars T. Kyllingstad wrote:
 
 In the "Function calls" thread the question of "which attributes should 
 be in the  -namespace" has again come up.


 Problem:
 Currently, there doesn't seem to be any clear definition of which 
 attributes should be prefixed with   and which shouldn't.  New 
 attributes get an  , while already existing attributes don't, and it all 
 seems a bit arbitrary.  Then again, we probably don't want *all* 
 attributes to be written with  , as that would just make code look messy:
To me attributes can make the code look uglier and, as pointed out, there there really is no clear seperation. So in my opinion, to keep the code looking clean attributes should only include those for the function, not its parameters. This prevents in, out, ref, const, etc. and allows for safe, property, etc.
D attributes[1] can't be part of parameters. That are InOut "modifiers" or storage classes[2] (there are some overlapping between the two, for example the keyword const is a storage class *and* an attribute, that can be the cause of confusion). [1] http://www.digitalmars.com/d/2.0/attribute.html [2] http://www.digitalmars.com/d/2.0/declaration.html -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ----------------------------------------------------------------------
Jan 28 2010
prev sibling parent reply Roman Ivanov <isroman-del ete-km.ru> writes:
Lars T. Kyllingstad Wrote:

 In the "Function calls" thread the question of "which attributes should 
 be in the  -namespace" has again come up.
 
 
 Problem:
 Currently, there doesn't seem to be any clear definition of which 
 attributes should be prefixed with   and which shouldn't.  New 
 attributes get an  , while already existing attributes don't, and it all 
 seems a bit arbitrary.  Then again, we probably don't want *all* 
 attributes to be written with  , as that would just make code look messy:
 
       safe  nothrow  private  property int foo() { ... }
I'm not saying D should do this, but in my opinion placing those things before function name and return type isn't very readable once you get more than two modifiers, regardless of whether you use or not. Compare: int foo() safe nothrow private property { ... } This is especially true if you have user-defined attributes, because you no longer have to think about where is return type name and where is the attribute. The method signature is visually separated by the parenthesis: SomeType foo() private somethingable { ... } vs somethingable private SomeType foo() { ... }
Jan 28 2010
parent Roman Ivanov <isroman-del ete-km.ru> writes:
Roman Ivanov Wrote:

 Lars T. Kyllingstad Wrote:
 
 In the "Function calls" thread the question of "which attributes should 
 be in the  -namespace" has again come up.
 
 
 Problem:
 Currently, there doesn't seem to be any clear definition of which 
 attributes should be prefixed with   and which shouldn't.  New 
 attributes get an  , while already existing attributes don't, and it all 
 seems a bit arbitrary.  Then again, we probably don't want *all* 
 attributes to be written with  , as that would just make code look messy:
 
       safe  nothrow  private  property int foo() { ... }
I'm not saying D should do this, but in my opinion placing those things before function name and return type isn't very readable once you get more than two modifiers, regardless of whether you use or not. Compare: int foo() safe nothrow private property { ... } This is especially true if you have user-defined attributes, because you no longer have to think about where is return type name and where is the attribute. The method signature is visually separated by the parenthesis: SomeType foo() private somethingable { ... } vs somethingable private SomeType foo() { ... }
I guess I didn't say what I wanted to say. IMO, Java syntax for such things is not the best one possible for readability. You have to scan the code very extensively to separate method signature from the surrounding fluff: FrameworkBinding(name="xyz") Retention(Whatever.RUNTIME) public final static synchronized MyClass function(AnotherClass) throws SomeException{ //... } I would rather have something like this: MyClass function(AnotherClass) public final static synchronized throws[SomeException] frameworkBinding[name="xyz"] retention[Whatever.RUNTIME] { //... } Why? Because you would know that the method signature is the first thing that starts after newlines. Also, using parenthesis for both method calls and annotations is visually confusing. Again, I understand that what you're discussing here is not quire the same as annotations, and I don't ask that D adopts the syntax I'm posting, but IMO there is a lesson about readability that can be learned here and that should be kept in mind. Ability to mentally and visually separate pieces of code with different functionality makes reading code _much_ simpler. So does the ability to "group" together the pieces of code that have similar functionality.
Jan 28 2010