August 18, 2017
On 18.08.2017 17:16, bitwise wrote:
> On Friday, 18 August 2017 at 01:43:42 UTC, Jonathan M Davis wrote:
>> [...]
>>
>> - Jonathan M Davis
> 
> Makes sense to me.
> 
> The first question that comes to mind is if the extra generality provided by DIP 1012 is actually useful, let alone, worth breaking changes. The rationale section of the DIP only mentions negating attributes, which is easily accomplished with what I suggested. Unless that section is expanded with additional practical use cases, then it doesn't seem worth the trouble to me.
> ...

It's a vastly better design, because it does not try to overfit to a single use case. E.g. it allows abstracting over attributes. You can have an alias that contains sequences of attributes and then apply the summary:

alias naughty = AliasSeq!(impure,system,throws,gc);
alias nice = AliasSeq!(pure,safe,nothrow,nogc);

@nice void foo();
@naughty void bar();


> The DIP mentions tagging a module declaration with default attributes. If the whole purpose of the DIP is to allow for negating attributes, why would you even need this change, when the DIP would effectively make it ok to put "@nogc: @safe: @etc:" at the top of the file?
> 
> My suggestion does not cover "inferred" as discussed in the DIP, but that could be achieved by letting something like "@default" reset all attributes for a given symbol.
> 
> I'll concede that DIP1012 makes more logical sense than the current state of things, but it seems like something that would be best achieved during a transition to a subsequent language version. It seems commonplace here, to discard suggestions based on their current viability, when it may be better to add them to a feature backlog that could be considered when talking about the possibility of a D3.
> 
> 

There are non-awkward backwards-compatible ways to implement DIP 1012.
August 18, 2017
On Friday, August 18, 2017 03:08:07 Nicholas Wilson via Digitalmars-d wrote:
> On Friday, 18 August 2017 at 01:43:42 UTC, Jonathan M Davis wrote:
> If you think that then I have clearly failed to express the DIP
> at all.
> It solves exactly that. I completely fail to see how it is a
> detriment to anything.
> The 'whole pile of other stuff' is reduced in further revisions
> to the DIP.

IMHO, the problem that needs solving is that you can't negate attributes, making stuff like

final:

problematic. DIP 1012 goes way beyond that, and I don't think that that extra stuff is at all worth having, and I do think that it's detrimental. For instance, as it stands, it's relatively easy to figure out whether @safe has been explicitly applied. You can look on the function and look for @safe: or @safe {} which affects it. The same goes for other attributes. But as soon as you can do stuff like create new attributes that combine attributes, you lose that completely. Suddenly. you have to worry about whatever attributes someone came up on their own for their project which apply @safe or final or @nogc or whatever. You can no longer search or grep for an attribute like @safe to see whether it applies. Similarly, having it be possible to alter the default attributes globally is incredibly bad IMHO. Suddenly, whether your module compiles or not could depend on what settings someone used for the default attributes. That should not be controlled externally. It should be part of the module just like whether a function or variable is const or not is part of the module and not defined externally. IMHO, it makes no sense whatsoever to have something external control attributes any more than it makes sense to control the return types or constness of symbols externally. That should be part of the declarations/definitions of the symbols in question. And slapping something like @safe: at the top of the module solves the problem of applying attributes to an entire module right now just fine except for the fact that you can't negate attributes, meaning that aside from the few that have multiple states (namely, the @safety and access level attributes), you can't alter the attributes on specific functions if you mark the whole module with a particular attribute. So, we really should have a solution for negating attributes, but I don't at all agree that the rest of what DIP 1012 is trying to do is beneficial.

I honestly think that what DIP 1012 is trying to do beyond making it possible to negate attributes is going to make the language worse and code harder to maintain. Yes, it will enable some things that you can't do now, but for the most part, I don't think that those things should be enabled. I don't want to have to deal with folks complaining that my library doesn't work right, because they tried a different default for the attributes with it. I don't want to have to worry about trying to get someone else's code to work because they assumed something about the default attributes that does not hold in my case. I don't want to have to track down every custom attribute that someone came up with just to see whether they actually apply attributes like @safe or nothrow, just so that I can see whether those attributes apply. I should be able to look at a module and see which attributes have been applied to the functions in that module without having to go searching elsewhere.

IMHO, what needs to be solved with the built-in attributes, is the ability to negate the ones that don't have multiple states. With that, what we have now will work just fine. The rest is completely undesirable.

- Jonathan M Davis

August 18, 2017
On Friday, 18 August 2017 at 15:16:55 UTC, bitwise wrote:
> On Friday, 18 August 2017 at 01:43:42 UTC, Jonathan M Davis wrote:
>> [...]
>>
>> - Jonathan M Davis
>
> Makes sense to me.
>
> The first question that comes to mind is if the extra generality provided by DIP 1012 is actually useful, let alone, worth breaking changes.

It fixes the non-inverability. They become regular attributes instead of keywords. This has the effect of separating their definition from their usage allowing you to manipulate them like normal attributes, see https://github.com/dlang/DIPs/pull/89/ for the most recent revision.

The only breaking changes are nothrow and pure get a leading '@'.
They will go through a proper deprecation process and I will be very surprised if anything breaks. The new symbols added to core.attributes can use `@future` if need be to further reduce the likelihood of any breaking changes.

> The rationale section of the DIP only mentions negating attributes, which is easily accomplished with what I suggested. Unless that section is expanded with additional practical use cases, then it doesn't seem worth the trouble to me.
>
> The DIP mentions tagging a module declaration with default attributes. If the whole purpose of the DIP is to allow for negating attributes, why would you even need this change, when the DIP would effectively make it ok to put "@nogc: @safe: @etc:" at the top of the file?

This is changed in pull #89.

> My suggestion does not cover "inferred" as discussed in the DIP, but that could be achieved by letting something like "@default" reset all attributes for a given symbol.

How would you know what attributes were in effect before?

> I'll concede that DIP1012 makes more logical sense than the current state of things, but it seems like something that would be best achieved during a transition to a subsequent language version.
>
> It seems commonplace here, to discard suggestions based on their current viability, when it may be better to add them to a feature backlog that could be considered when talking about the possibility of a D3.

Why? Breakage will be completely contained with transitional behaviour, i.e. the compiler will treat pure as @pure and nothrow as @nothrow. I can't think of any other facets that would warrant semi-indefinite delay.

August 19, 2017
On Friday, 18 August 2017 at 23:11:34 UTC, Jonathan M Davis wrote:
> On Friday, August 18, 2017 03:08:07 Nicholas Wilson via Digitalmars-d wrote:
>> On Friday, 18 August 2017 at 01:43:42 UTC, Jonathan M Davis wrote:
>> If you think that then I have clearly failed to express the DIP
>> at all.
>> It solves exactly that. I completely fail to see how it is a
>> detriment to anything.
>> The 'whole pile of other stuff' is reduced in further revisions
>> to the DIP.
>
> IMHO, the problem that needs solving is that you can't negate attributes, making stuff like
>
> final:
>
> problematic. DIP 1012 goes way beyond that, and I don't think that that extra stuff is at all worth having, and I do think that it's detrimental. For instance, as it stands, it's relatively easy to figure out whether @safe has been explicitly applied. You can look on the function and look for @safe: or @safe {} which affects it. The same goes for other attributes. But as soon as you can do stuff like create new attributes that combine attributes, you lose that completely. Suddenly. you have to worry about whatever attributes someone came up on their own for their project which apply @safe or final or @nogc or whatever. You can no longer search or grep for an attribute like @safe to see whether it applies.

As I have said before that is a deliberate feature of the DIP and not an incidental side product. Many people have requested such a feature. It also allows the DIP to solve the export problem:

```d
 version(MyLib_Build)
     enum MyLibExport = dynamicExport;
 else
     enum MyLibExport = dynamicImport;

 // Exported when building the shared object,
 // imported when linking against the shared object.
 @MyLibExport void foo(int x) { ... }
  ```
I get that you dislike that feature: yes you lose the ability to see it directly. grep still works (it might take more searches) and so does the documentation.

> Similarly, having it be possible to alter the default attributes globally is incredibly bad IMHO. Suddenly, whether your module compiles or not could depend on what settings someone used for the default attributes. That should not be controlled externally. It should be part of the module just like whether a function or variable is const or not is part of the module and not defined externally. IMHO, it makes no sense whatsoever to have something external control attributes any more than it makes sense to control the return types or constness of symbols externally. That should be part of the declarations/definitions of the symbols in question.

That is a separable feature of the DIP, i.e. the DIP still functions without it, and if it truly so incredibly bad more people will say so.

But, say you are developing for an embedded platform: you have no room for libunwind or exception table and can't use the gc. You see some library, libFoo, and you think "Aha! that does exactly what I need", then you think can I use it? is this library @nothrow @nogc?
You could consult the documentation, but that doesn't tell you because there are a bunch of templates that dont have explicit attributes. You could try altering the examples to be @nothrow @nogc, or you could try to build the whole library as @nothrow @nogc and get error messages closer to the site of use.
Yes it is niché, but it has its uses.

>[...] , but I don't at all agree that the rest of
> what DIP 1012 is trying to do is beneficial.

It fixes export, allows grouping and manipulation of lists of attributes

> I honestly think that what DIP 1012 is trying to do beyond making it possible to negate attributes

Yes,

>is going to make the language worse and code harder to maintain.

No.

> Yes, it will enable some things that you can't do now, but for the most part, I don't think that those things should be enabled. I don't want to have to deal with folks complaining that my library doesn't work right, because they tried a different default for the attributes with it.

Then that library is not for them.

> I don't want to have to worry about trying to get someone else's code to work because they assumed something about the default attributes that does not hold in my case.

Then the library is not for you.

Having to change the default attributes will be a rare occurrence (embedded (nothrow, nogc final) security critical (safe).

> I don't want to have to track down every custom attribute that someone came up with just to see whether they actually apply attributes like @safe or nothrow, just so that I can see whether those attributes apply.

-vcg-ast, documentation. But really, how others do you go: I really need to know if that some function has a particular combination of attributes (serious)?

>I should be able to look at a
> module and see which attributes have been applied to the functions in that module without having to go searching elsewhere.
>
> IMHO, what needs to be solved with the built-in attributes, is the ability to negate the ones that don't have multiple states. With that, what we have now will work just fine. The rest is completely undesirable.

Again I reject that notion.

August 19, 2017
On Saturday, 19 August 2017 at 00:37:06 UTC, Nicholas Wilson wrote:
>
> Having to change the default attributes will be a rare occurrence (embedded (nothrow, nogc final) security critical (safe).
>

My reading of that updated DIP is that you can only change the default attributes by hacking on DRuntime. If a project has a custom runtime, I would figure most people would mention it somewhere.
August 19, 2017
On 18 August 2017 at 02:32, bitwise via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> This came to mind while working on a set of containers.
>
> @safety often comes with a performance cost. For example, any container that wants to give out a range or iterator has to have a ref-counted or GC allocted payload to ensure safety. In a high-performance context though, the performance hit may be unacceptable.
>

This sounds like a job for `scope`.
Eg, given a container, the function that returns the range/iterator should
return a `scope` attributed range/iterator. This should insist that the
lifetime of the range that is returned be no longer than the container that
issued it.
We've needed scope to address these issues for a very long time, and it
finally arrived! I'm not sure how far it extends yet though, it's not well
documented yet, and I haven't seen it get a lot of action. I'm not sure
where the boundaries are.


August 19, 2017
On Saturday, 19 August 2017 at 02:00:47 UTC, jmh530 wrote:
> On Saturday, 19 August 2017 at 00:37:06 UTC, Nicholas Wilson wrote:
>>
>> Having to change the default attributes will be a rare occurrence (embedded (nothrow, nogc final) security critical (safe).
>>
>
> My reading of that updated DIP is that you can only change the default attributes by hacking on DRuntime.

Hacking the runtime is certainly one way to achieve changing the default attributes.
However having them as regular attributes means that is is possible to do configuration by version statements, which is a) much easier than hacking the runtime and b) causes much less fragmentation.

I don't think we want to encourage people to change the default attributes, but I think its one of those features that we have in D for those who know what they're doing (e.g =void) and don't want to get in their way of doing so.

> If a project has a custom runtime, I would figure most people would mention it somewhere.

I would hope so!
August 19, 2017
On Friday, 18 August 2017 at 18:15:33 UTC, Timon Gehr wrote:
> [...]
>
> alias naughty = AliasSeq!(impure,system,throws,gc);
> alias nice = AliasSeq!(pure,safe,nothrow,nogc);
>
> @nice void foo();
> @naughty void bar();

We have to consider the potential for abuse.

For example, D's templates are great - but it doesn't mean that if you're making a math library, that you should template your matrix class on it's dimensions, just to fill it with static if's because half of the functionality only applies to a single dimension. Especially when you typically need 2-3 different versions at most(mat2, mat3, mat4). People do it though.

If things did turn out to be as simple as the example you posted, then I could see it being a useful way to hide some of D's painful attribute bloat, but I've got a feeling we'd start seeing things like "nice", "nicer", "nicest", "niceInDebugModeButNotReleaseModeUnlessAssertsAreEnabled", etc.....
August 19, 2017
On Friday, 18 August 2017 at 23:48:05 UTC, Nicholas Wilson wrote:
>
> The only breaking changes are nothrow and pure get a leading '@'.
> They will go through a proper deprecation process and I will be very surprised if anything breaks. The new symbols added to core.attributes can use `@future` if need be to further reduce the likelihood of any breaking changes.

While the difference in attribute style(@, or no @) isn't that hard to deal with in practice, I am definitely in favor of a more consistent scheme. The current inconsistency looks bad, and IMO, that's a big deal. It makes D look tacky, and easy to dismiss.

> How would you know what attributes were in effect before?

It wouldn't matter if your intention was to clobber them anyways with @default. And if you only wanted to clobber @nogc, you could use @nogc(false), and it still wouldn't matter what the inferred attribute set was.


I'm still concerned about having to read code that's laced full of custom attributes, the resolution of which may span several files, templates, etc.

I also think this type of thing could have a detrimental effect on modularity when you end up having to include "myAttribs.d" in every single file you want to work on. I would much rather have a flexible in-language solution, or a solution that didn't require me to define my own attributes.
August 19, 2017
On Saturday, 19 August 2017 at 16:02:27 UTC, bitwise wrote:
> We have to consider the potential for abuse.

I don't like measuring features on the potential for abuse, but this feature cries for abuse.  Even in the simpler form of your proposal.

Let's say there are two functions with conditional @safe

f(T)(...) @safe(!hasAliasing!T) {...}
g(bool B)(...) @safe(B) {...}

and we combine them into another function,

h(T,bool B) @safe(!hasAliasing!T && B) {
  f(T)(...);
  g(B)(...);
}

then in the correct @safe specification there is an additional clause for every conditionally-safe function.

This doesn't scale well.

So the guideline would be to use your feature very rarely and only if it's obvious from the meaning of the template arguments; if it gets too complicated, just don't specify it.

Which would mean the feature should only be used in few corner cases, and is thus not worth the cost of complicating the language.


You already commented on the other usage of dip 1012, the @nice and @naughty attributes.  They just don't scale in a similar way.


C++ has had the same feature for some time: noexcept(true) means noexcept, noexcept(false) means an exception may be thrown (of course this works with any constant expressions).
I just grepped through Boost and I have found 53 uses of noexcept(expression), from 5264 total uses of noexcept (excluding the math library). And Boost is one of those libraries that are overly precise with such things to a degree that the code becomes unreadable.  In code outside of Boost and the standard library, noexcept(expression) it is basically unused.