www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - RFC: DIP draft for "Compiler-defined Attribute Consistency"

reply Rune Morling <ermo serpentos.com> writes:
Hi All,

After asking around in the #d channel on the Libera.Chat IRC 
network, there seems to be consensus that it would make sense to 
propose an updated version of 
[DIP64](https://wiki.dlang.org/DIP64) that only focuses on 
Compiler-defined Attribute Consistency.

The current DIP draft can be found 
[here](https://github.com/ermo/DIPs/blob/compiler-defined-attribute-consistency/DIPs/1NNN-RM.md).

Comments very welcome.

Best Regards,

Rune Morling

(Note that this is a 
[cross-post](https://forum.dlang.org/thread/tctflsorkcaxcigth
xz forum.dlang.org) from [Development
Internals](https://forum.dlang.org/group/internals) in order to get in front of
more eyeballs)
Jul 14
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
Two improvements to the grammar:

1. Don't repeat the spec, use ... to signify a copy
2. Use diff syntax for syntax highlighting

Note: there is already a tool for upgrading D code, DFix 
https://github.com/dlang-community/dfix
Jul 14
parent Rune Morling <ermo serpentos.com> writes:
On Wednesday, 14 July 2021 at 15:05:28 UTC, rikki cattermole 
wrote:
 Two improvements to the grammar:

 1. Don't repeat the spec, use ... to signify a copy
 2. Use diff syntax for syntax highlighting

 Note: there is already a tool for upgrading D code, DFix 
 https://github.com/dlang-community/dfix
Both suggestions have been implemented in the latest version of the draft. Thanks!
Jul 14
prev sibling next sibling parent reply user1234 <user1234 12.de> writes:
On Wednesday, 14 July 2021 at 15:01:05 UTC, Rune Morling wrote:
 Hi All,

 After asking around in the #d channel on the Libera.Chat IRC 
 network, there seems to be consensus that it would make sense 
 to propose an updated version of 
 [DIP64](https://wiki.dlang.org/DIP64) that only focuses on 
 Compiler-defined Attribute Consistency.

 The current DIP draft can be found 
 [here](https://github.com/ermo/DIPs/blob/compiler-defined-attribute-consistency/DIPs/1NNN-RM.md).

 Comments very welcome.

 Best Regards,

 Rune Morling

 (Note that this is a 
 [cross-post](https://forum.dlang.org/thread/tctflsorkcaxcigth
xz forum.dlang.org) from [Development
Internals](https://forum.dlang.org/group/internals) in order to get in front of
more eyeballs)
I'm worried not to see ` const` and ` inout`.
Jul 14
next sibling parent reply Andrea Fontana <nospam example.org> writes:
On Wednesday, 14 July 2021 at 15:54:06 UTC, user1234 wrote:
 Comments very welcome.
I don't like that attr is colliding with UDA.
Jul 14
next sibling parent Adam D Ruppe <destructionator gmail.com> writes:
On Wednesday, 14 July 2021 at 16:02:01 UTC, Andrea Fontana wrote:

 viceversa).
I think that ship sailed 10 years ago.
Jul 14
prev sibling next sibling parent reply Dennis <dkorpel gmail.com> writes:
On Wednesday, 14 July 2021 at 16:02:01 UTC, Andrea Fontana wrote:

 viceversa).
That conflicts with #line directives.
Jul 14
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 15/07/2021 4:19 AM, Dennis wrote:
 On Wednesday, 14 July 2021 at 16:02:01 UTC, Andrea Fontana wrote:

That conflicts with #line directives.
It doesn't. #line checks for the identifier line as part of the lexer, and language defined attributes do not include line. So no conflicts :)
Jul 14
parent reply Rune Morling <ermo serpentos.com> writes:
On Thursday, 15 July 2021 at 00:59:28 UTC, rikki cattermole wrote:
 On 15/07/2021 4:19 AM, Dennis wrote:
 On Wednesday, 14 July 2021 at 16:02:01 UTC, Andrea Fontana 
 wrote:

 viceversa).
That conflicts with #line directives.
It doesn't. #line checks for the identifier line as part of the lexer, and language defined attributes do not include line. So no conflicts :)
Is e.g. ` +myuda`, ` -myuda` or ` _myuda` legal? As long as you can decorate with a consistent extra single character, wouldn't it be entirely possible (and perhaps even advantageous?) to use a commonly accepted best practice/idiom in order to distinguish user-defined attributes from compiler-defined attributes without needing to change the grammar?
Jul 15
parent rikki cattermole <rikki cattermole.co.nz> writes:
On 16/07/2021 7:26 AM, Rune Morling wrote:
 
 Is e.g. ` +myuda`, ` -myuda` or ` _myuda` legal?
_ may be in an identifier, so that one is legal.
 As long as you can decorate with a consistent extra single character, 
 wouldn't it be entirely possible (and perhaps even advantageous?) to use 
 a commonly accepted best practice/idiom in order to distinguish 
 user-defined attributes from compiler-defined attributes without needing 
 to change the grammar?
Nah. The moment we start changing rules around what an identifier means, that's symbol lookup. We really don't want to add more special cases there.
Jul 15
prev sibling parent reply bauss <jj_1337 live.dk> writes:
On Wednesday, 14 July 2021 at 16:02:01 UTC, Andrea Fontana wrote:
 On Wednesday, 14 July 2021 at 15:54:06 UTC, user1234 wrote:
 Comments very welcome.
I don't like that attr is colliding with UDA. viceversa).
I would rather have seen built-in attributes having no prefix ex. just safe, nogc etc. Basically the opposite of making the rest of the attributes having too.
Jul 15
next sibling parent Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Friday, 16 July 2021 at 06:47:57 UTC, bauss wrote:
 On Wednesday, 14 July 2021 at 16:02:01 UTC, Andrea Fontana 
 wrote:
 On Wednesday, 14 July 2021 at 15:54:06 UTC, user1234 wrote:
 Comments very welcome.
I don't like that attr is colliding with UDA. viceversa).
I would rather have seen built-in attributes having no prefix ex. just safe, nogc etc. Basically the opposite of making the rest of the attributes having too.
Making them have prefix would allow to make them a simple uda defined in druntime, which the compiler then would check for them and apply extra requirements over them. Imho, this would actually simplify compiler code. - Alexandru
Jul 16
prev sibling parent Guillaume Piolat <first.name domain.tld> writes:
On Friday, 16 July 2021 at 06:47:57 UTC, bauss wrote:
 I don't like that  attr is colliding with UDA.

 viceversa).
I would rather have seen built-in attributes having no prefix ex. just safe, nogc etc. Basically the opposite of making the rest of the attributes having too.
+10.447464 More syntax was fine when the attributes were new, but it seems to me what is needed would be more "normalcy": safe, trusted, nogc If you're calling your variable safe or nogc, then well they are now keywords: choose proper names.
Jul 18
prev sibling next sibling parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Wednesday, 14 July 2021 at 15:54:06 UTC, user1234 wrote:
 I'm worried not to see ` const` and ` inout`.
eh those are type constructors not attributes.
Jul 14
parent reply Ogi <ogion.art gmail.com> writes:
On Wednesday, 14 July 2021 at 16:18:11 UTC, Adam D Ruppe wrote:
 On Wednesday, 14 July 2021 at 15:54:06 UTC, user1234 wrote:
 I'm worried not to see ` const` and ` inout`.
eh those are type constructors not attributes.
Except when they are attributes — when applied to member functions. It makes no sense that `const int` variable is a constant integer while `const int function()` is a constant member function of some struct or class that returns non-constant integer. We should introduce ` const` (and others) as a proper function attribute and deprecate the ambiguous `const int function()` syntax.
Jul 14
parent Dennis <dkorpel gmail.com> writes:
On Wednesday, 14 July 2021 at 16:55:30 UTC, Ogi wrote:
 Except when they are attributes — when applied to member 
 functions.
No, then they are still type constructors. This: ```D struct S { void f() const { } } ``` Is roughly equal to this: ```D void f(ref const S this) { } ```
 It makes no sense that `const int` variable is a constant 
 integer while `const int function()` is a constant member 
 function of some struct or class that returns non-constant 
 integer.
return, scope, const, inout, immutable, shared outside the parameter list all apply to the implicit `this` parameter. The syntax is confusing, but there are multiple solutions. Adding ` ` variants for all type constructors is one of them, but that doesn't make it relevant to a DIP about function attributes.
Jul 14
prev sibling next sibling parent reply Dennis <dkorpel gmail.com> writes:
On Wednesday, 14 July 2021 at 15:54:06 UTC, user1234 wrote:
 I'm worried not to see ` const` and ` inout`.
Those are type constructors, not attributes.
Jul 14
parent reply user1234 <user1234 12.de> writes:
On Wednesday, 14 July 2021 at 16:18:21 UTC, Dennis wrote:
 On Wednesday, 14 July 2021 at 15:54:06 UTC, user1234 wrote:
 I'm worried not to see ` const` and ` inout`.
Those are type constructors, not attributes.
I reffered about the [attribute form of const](https://dlang.org/spec/attribute.html#const), e.g we would have ```c struct S { void v(T)(const T t) const {} } ``` and very obviously the typector and param storage class would continue to use the keyword, i.e no deprecation for those
Jul 14
parent Dennis <dkorpel gmail.com> writes:
On Wednesday, 14 July 2021 at 17:45:34 UTC, user1234 wrote:
 On Wednesday, 14 July 2021 at 16:18:21 UTC, Dennis wrote:
 On Wednesday, 14 July 2021 at 15:54:06 UTC, user1234 wrote:
 I'm worried not to see ` const` and ` inout`.
Those are type constructors, not attributes.
I reffered about the [attribute form of const](https://dlang.org/spec/attribute.html#const), e.g we would have
I didn't know the spec considers them attributes, I stand corrected. I still think it's a separate proposal though, since this DIP is about consistency among function attributes, not the confusing syntax of member functions with type attributes.
Jul 14
prev sibling parent Ogi <ogion.art gmail.com> writes:
On Wednesday, 14 July 2021 at 15:54:06 UTC, user1234 wrote:
 I'm worried not to see ` const` and ` inout`.
Also ` immutable` and ` shared`.
Jul 14
prev sibling next sibling parent reply Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Wednesday, 14 July 2021 at 15:01:05 UTC, Rune Morling wrote:
 Hi All,
 ...
 Comments very welcome.
What about making those attributes not just prefixed with , but fully fledged UDA? From the point of view of compile time code this would remove the necessity in strange syntax for is expression to get them. You'd just fetch them as any other uda. Also this will allow us to extend these attributes with fields! Say for example: safe(disabled.yes) Older compiler would just ignore this, but newer could take hints and other additional info defined on these udas for better optimization, or improved checks, or just for informational purposes. Another example: deprecated("See xxx for this functionality") Best regards, Alexandru.
Jul 16
next sibling parent Petar Kirov [ZombineDev] <petar.p.kirov gmail.com> writes:
On Friday, 16 July 2021 at 09:06:26 UTC, Alexandru Ermicioi wrote:
 On Wednesday, 14 July 2021 at 15:01:05 UTC, Rune Morling wrote:
 Hi All,
 ...
 Comments very welcome.
What about making those attributes not just prefixed with , but fully fledged UDA? From the point of view of compile time code this would remove the necessity in strange syntax for is expression to get them. You'd just fetch them as any other uda. Also this will allow us to extend these attributes with fields! Say for example: safe(disabled.yes) Older compiler would just ignore this, but newer could take hints and other additional info defined on these udas for better optimization, or improved checks, or just for informational purposes. Another example: deprecated("See xxx for this functionality") Best regards, Alexandru.
I absolutely agree! I started writing a longer post on exactly this topic, but you beat me to it :P
Jul 16
prev sibling next sibling parent reply vit <vit vit.vit> writes:
On Friday, 16 July 2021 at 09:06:26 UTC, Alexandru Ermicioi wrote:
 On Wednesday, 14 July 2021 at 15:01:05 UTC, Rune Morling wrote:
 Hi All,
 ...
 Comments very welcome.
What about making those attributes not just prefixed with , but fully fledged UDA? From the point of view of compile time code this would remove the necessity in strange syntax for is expression to get them. You'd just fetch them as any other uda. Also this will allow us to extend these attributes with fields! Say for example: safe(disabled.yes) Older compiler would just ignore this, but newer could take hints and other additional info defined on these udas for better optimization, or improved checks, or just for informational purposes. Another example: deprecated("See xxx for this functionality") Best regards, Alexandru.
And make attributes symbols: ``` template Pure(bool con){ import std.meta : AliasSeq; static if(con) alias Pure = pure; //this is not valid else alias Pure = AliasSeq!(); } //conditional atributes: void foo() (Pure!true){ //expand to `pure` } void bar() (Pure!false){ //expand to `()` } ```
Jul 16
parent Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Friday, 16 July 2021 at 10:17:39 UTC, vit wrote:

 And make attributes symbols:
If they are UDA, then they are symbols. I.e in object.d you'd have struct defs for each lang defined attribute: ``` struct safe {...} struct nogc {...} struct deprecated {...} ``` This consequently means that you can employ them in a template like in your example, or ctfe function that is put as an annotation: ``` void textedDeprecate(T...)(T args) { return deprecated(text(args)); } textedDeprecate("this is obsolete since ", 1.0) struct Obsolete { } ```
Jul 16
prev sibling parent Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Friday, 16 July 2021 at 09:06:26 UTC, Alexandru Ermicioi wrote:
 ...
To add one more strong point on making them uda: Suppose that you have a collection interface Collection(T). In order to make it portable and usable in safe pure or nogc code, the methods in collection should infer the properties of stored entities. This is not possible at the moment since you can't define these attributes based on a condition. However, if you make them UDA this means that you can create templates that check the capabilities of the stored entities and alias itself to the supported tuple of features, say Foo is safe but nogc, then instantiation of collection will become safe Collection!Foo, while for nogc but unsafe Noo struct it will become nogc Collection!Noo. Regards, Alexandru.
Jul 16
prev sibling next sibling parent reply Dennis <dkorpel gmail.com> writes:
On Wednesday, 14 July 2021 at 15:01:05 UTC, Rune Morling wrote:
 Comments very welcome.
I just noticed there is an issue for this: https://issues.dlang.org/show_bug.cgi?id=13388 And a discussion: https://forum.dlang.org/post/rtwbtxigfeupvykpbamh forum.dlang.org And a PR that got merged: https://github.com/dlang/dmd/pull/4341 But reverted because there was no consensus in the discussion yet: https://github.com/dlang/dmd/pull/4349
Jul 17
parent reply Rune Morling <ermo serpentos.com> writes:
On Saturday, 17 July 2021 at 10:51:20 UTC, Dennis wrote:
 On Wednesday, 14 July 2021 at 15:01:05 UTC, Rune Morling wrote:
 Comments very welcome.
I just noticed there is an issue for this: https://issues.dlang.org/show_bug.cgi?id=13388 And a discussion: https://forum.dlang.org/post/rtwbtxigfeupvykpbamh forum.dlang.org And a PR that got merged: https://github.com/dlang/dmd/pull/4341 But reverted because there was no consensus in the discussion yet: https://github.com/dlang/dmd/pull/4349
Thank you for the investigation and for listing the prior discussions. I've read all of it and the most pertinent summary of the situation I could find was this:
 The problem is that no proposal has been given which really 
 makes the attribute names
 consistent in a way that makes sense to actually change to.
 We may agree that the status quo is ugly, but how things should 
 be changed is not
 at all clear. So, we don't even know how we'd want to change 
 the language to fix
 the attribute situation.

 And even if dfix makes it easy to change code, breaking code 
 still causes problems.
 So, while dfix will definitely help reduce the pain when we do 
 decide to make changes
 to the language which will require changing existing code, it 
 doesn't make the language
 changes free. The fact that dfix could make it easy to change 
 existing code does not
 mean that it's okay to make breaking changes without a very 
 good reason behind them.

 [source](https://issues.dlang.org/show_bug.cgi?id=13388#c33)
In other words, unless I/we can come up with an "algorithm" for deciding when something should be an -attribute, the DIP I've proposed has little merit in that it's basically just proposing that we shuffle attributes around on a whim. Personally, I'm currently leaning towards something that describes how a keyword/attribute changes the amount of checks that the compiler makes so that it's akin to switching to a different "mode" of compilation with attendant extra/fewer checks/limits on functions.
Jul 21
parent reply Paul Backus <snarwin gmail.com> writes:
On Wednesday, 21 July 2021 at 20:00:32 UTC, Rune Morling wrote:
 In other words, unless I/we can come up with an "algorithm" for 
 deciding when something should be an  -attribute, the DIP I've 
 proposed has little merit in that it's basically just proposing 
 that we shuffle attributes around on a whim.
Here's my take. D's attributes can be divided, conceptually, into a few different "groups" of related attributes. Some examples are: 1. The **Type Constructor Group**: `const`, `immutable`, `inout`, and `shared`. 2. The **Inheritance Group**: `final`, `override`, and `abstract`. 3. The **Visibility Group**: `public`, `private`, `protected`, `package`, and `export`. 4. The **Function Attribute Group**: `pure`, `nothrow`, ` nogc`, ` safe`, ` system`, ` trusted`, ` property`, and ` live`. ...and so on. The rule I propose is that *within a single group*, use of ` ` should be consistent--either all of the attributes should use it, or none of them should. Of course this invites some debate as to where exactly one ought to draw the group boundaries (e.g., should ` property` be counted as part of the function attribute group, or is it a separate thing?). But it is at least a step forward from the current discussion, which does not even acknowledge that these groups exist in the first place.
Jul 21
parent reply Rune Morling <ermo serpentos.com> writes:
On Wednesday, 21 July 2021 at 20:46:01 UTC, Paul Backus wrote:
 Here's my take.

 D's attributes can be divided, conceptually, into a few 
 different "groups" of related attributes. Some examples are:

 (...)

 4. The **Function Attribute Group**: `pure`, `nothrow`, 
 ` nogc`, ` safe`, ` system`, ` trusted`, ` property`, and 
 ` live`.

 ...and so on.

 The rule I propose is that *within a single group*, use of ` ` 
 should be consistent--either all of the attributes should use 
 it, or none of them should.

 Of course this invites some debate as to where exactly one 
 ought to draw the group boundaries (e.g., should ` property` be 
 counted as part of the function attribute group, or is it a 
 separate thing?). But it is at least a step forward from the 
 current discussion, which does not even acknowledge that these 
 groups exist in the first place.
I like this approach. Consider the idea internally consistent groups acknowledged. For the current DIP to go anywhere, we'd probably need to agree/converge on how to divide all attributes into a reasonable set of groups? Once we have that, we can then discuss inter-group consistency and propose the relevant changes. What other group distinctions would make sense (if any)?
Jul 21
parent Paul Backus <snarwin gmail.com> writes:
On Wednesday, 21 July 2021 at 22:43:49 UTC, Rune Morling wrote:
 For the current DIP to go anywhere, we'd probably need to 
 agree/converge on how to divide all attributes into a 
 reasonable set of groups?
If the proposal is just to allow ` pure` and ` nothrow` (and ` throw`, once DIP 1029 [1] is implemented), I think it would probably be sufficient to make the case that the function attributes form a distinct group. [1] https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1029.md
 Once we have that, we can then discuss inter-group consistency 
 and propose the relevant changes.

 What other group distinctions would make sense (if any)?
As far as I know, the only groups that include both ` ` and non-` ` attributes are (1) the function attributes, and (2) the group consisting of `deprecated` and ` __future`.
Jul 21
prev sibling parent reply Nick Treleaven <nick geany.org> writes:
On Wednesday, 14 July 2021 at 15:01:05 UTC, Rune Morling wrote:
 The current DIP draft can be found 
 [here](https://github.com/ermo/DIPs/blob/compiler-defined-attribute-consistency/DIPs/1NNN-RM.md).
I support using built-in attributes when they only affect functions, not parameters, variables or fields. This would mean only a few minor additions to increase consistency. For this we need to add override, abstract, final (' final class' only affects a class's methods, not field members) to the DIP.
Jul 18
parent reply Rune Morling <ermo serpentos.com> writes:
On Sunday, 18 July 2021 at 09:50:30 UTC, Nick Treleaven wrote:
 On Wednesday, 14 July 2021 at 15:01:05 UTC, Rune Morling wrote:
 The current DIP draft can be found 
 [here](https://github.com/ermo/DIPs/blob/compiler-defined-attribute-consistency/DIPs/1NNN-RM.md).
I support using built-in attributes when they only affect functions, not parameters, variables or fields. This would mean only a few minor additions to increase consistency. For this we need to add override, abstract, final (' final class' only affects a class's methods, not field members) to the DIP.
In keeping with my last post, what is your proposed reasoning for using override, abstract and final (= making them -attributes)? As I see it, nogc, nothrow, pure and safe all define that something out of the ordinary or special is happening on a language/compiler "meta-level" rather than being directly associated with/derived from with class/type hierarchy functionality? My take: - abstract says something about the type of a class/function (part of the OOP hierarchy) - final says that a function in a class cannot be overridden (part of the OOP hierarchy) - override says that a function in a class is being overridden (part of the OOP hierarchy) Can you help me understand what I might be missing here?
Jul 21
parent reply Nick Treleaven <nick geany.org> writes:
On Wednesday, 21 July 2021 at 20:13:16 UTC, Rune Morling wrote:
 - abstract says something about the type of a class/function 
 (part of the OOP hierarchy)
 - final says that a function in a class cannot be overridden 
 (part of the OOP hierarchy)
 - override says that a function in a class is being overridden 
 (part of the OOP hierarchy)
None of these 3 attributes change the actual type of the class, they only affect methods in the class or methods in a subclass. What I'm saying is that it's simpler and easier to remember to use attribute syntax for attributes that only affect a function/method, rather than that rule except attributes that are related to OOP don't use . Really using `abstract class` or `final class` is just another way of writing `class Foo {final: ...` or `class Foo {abstract: ...`. So the attributes actually apply to the methods.
Jul 26
parent Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Monday, 26 July 2021 at 12:07:01 UTC, Nick Treleaven wrote:
 Really using `abstract class` or `final class` is just another 
 way of writing `class Foo {final: ...` or `class Foo {abstract: 
 ...`. So the attributes actually apply to the methods.
Not sure about final modifier. By your definition you would be able to extend a final class, which is not right.
Jul 27