May 31

On Thursday, 30 May 2024 at 18:35:36 UTC, Atila Neves wrote:

>

https://github.com/atilaneves/DIPs/blob/safe-by-default/safe-by-default.md

Destroy!

Neutral.
I think safe by default is of no benefit to me.

However I'd support this change (as an edition) since there are easy ways out and default do matter, I've remarked if you don't write @safe right from the start it's not going to happen afterwards (but this is also a testament to how relatively useless it is to be @safe in the first place imo).

May 31
On Friday, 31 May 2024 at 11:42:13 UTC, Dukc wrote:
> Nick Treleaven kirjoitti 31.5.2024 klo 12.18:
>> @safe should mean mechanically checked for accidental memory-safety violations - that is a more useful definition. Allowing non-extern(D) linkage prototypes to be @safe breaks that principle and makes @safe prototypes a minefield.
>
> I agree in principle, but note this is orthogonal to the DIP. D allows declaring external C functions as `@safe` right now. The DIP should not make it any worse, and it also doesn't prevent a separate proposal that would say that external non-D linked functions must be either `@trusted` or `@system`.

This. I don't think we can stop programmers intent on lying to the compiler. As mentioned there's already `pragma(mangle)`, they can write assembly, ...

I think that if there's a body written in D somewhere, it's unlikely someone will manually write a declaration and use the wrong attribute by mistake. And if there isn't, then they will have had to deliberately have picked an attribute.
May 31
On Friday, May 31, 2024 7:06:16 AM MDT Paul Backus via dip.ideas wrote:
> Inference also solves the wrong-default problem for @nogc, nothrow, and pure, in addition to @safe, without the need for any additional -preview switches or migrations. Asking users to migrate from @system-by-default to @safe-by-default may be doable, but can we really ask them to do the same thing *three more times* for the other attributes?

I think that you will have a hard time finding a consensus on the idea that any of those should be the default. It may be that most folks would agree that @safe should be the default, but I'd be _very_ surprised to see a consensus on the others (especially @nogc).

Personally, I'm increasingly of the opinion that most attributes are actively detrimental rather than beneficial, and I don't want to see them be forced or for them become the default. I think that there's a good argument for making @safe the default given that you usually do want most code to be @safe, and @trusted makes it fairly easy to have @system code be used by @safe code, but the others often simply do not work with code and get in the way of making changes - especially with larger code bases. So, I very much hope that we don't change the default attributes beyond possibly @safe.

And considering that DIP 1000 is a thing, I'm definitely concerned about what the repercussions of making @safe the default are, since DIP 1000 makes life _way_ too complicated IMHO, and inference will trigger it in a number of cases (to the point that I would be tempted to slap @system on everything and give up on any benefits from @safe just to escape having to deal with DIP 1000). If DIP 1000 weren't a thing, then I'd probably be okay with @safe being the default, but I think that all of these attempts to make malloc @safe instead of just saying that if you want @safe without @trusted, you use the GC, are adding way too much complexity to the language, and making @safe the default potentially forces you into that mess - either that or forces you to slap @system all over the place.

Having more attribute inference may help with some of these issues, but personally, I just want to avoid most attributes in general and not have to deal with stuff like pure, because inevitably, at some point, you have to figure out how to strip it from your code to get something to work.

- Jonathan M Davis



May 31

On Friday, 31 May 2024 at 12:50:55 UTC, jmh530 wrote:

>

On Thursday, 30 May 2024 at 18:35:36 UTC, Atila Neves wrote:

>

https://github.com/atilaneves/DIPs/blob/safe-by-default/safe-by-default.md

Destroy!

I was glad to see some compromise on this. I'm still not 100% behind it, but it is less objectionable than before, IMO.

In terms of qualms, here is an example of a module that contains a mix of code, some of which is bringing in compiler intrinsics that don't have function bodies and part of it is additional functions:
https://github.com/libmir/mir-core/blob/master/source/mir/math/common.d
Under this DIP, this would no longer compile,

It wouldn't compile because of the intrinsics? Wouldn't the fix then be to add attributes to them?

May 31

On Friday, 31 May 2024 at 13:06:16 UTC, Paul Backus wrote:

>

On Thursday, 30 May 2024 at 18:35:36 UTC, Atila Neves wrote:

>

https://github.com/atilaneves/DIPs/blob/safe-by-default/safe-by-default.md

Destroy!

I agree completely that "having [@safe] be opt-in makes it hard to use in practice" and that "defaults matter". However, I think that implementing [Universal Function Attribute Inference][1] would be a better way to address the shortcomings of the current defaults.

It might be; it's something Walter and I have discussed before, and the reason that didn't go forward is due to the potential compile-time performance penalties. If it's doable in a fast way it would kill two birds with one stone, for sure.

>

In ["Thoughts on Backward Compatibility"][2], I tried to figure out why some breaking changes succeed and others fail. The conclusion I came to was that breaking changes are most successful when:

  1. Migration is easy, or
  2. The change serves a goal that has strong buy-in from users

While there is a vocal minority in the D community who strongly support @safe (a group in which I include myself), I do not believe that @safe has strong buy-in from D programmers as a whole. In other words, this proposal cannot satisfy condition (2). It follows that, if we would like it to succeed, it must satisfy condition (1).

Sadly, I do not think migration to -preview=safedefault will be particularly easy. By the DIP's own admission, it "will likely break a lot of code". Even if editions allow us to mix pre-migration and post-migration code in the same project, the burden of migrating to -preview=safedefault will likely hurt the adoption of new editions, and cause projects that would otherwise upgrade to get "stuck" in the @system-by-default edition.
(It is also conceivable that new projects started by D programmers who don't care about @safe will choose the old, @system-by-default edition specifically to avoid the hassle of adding explicit @system attributes to their code.)

I was going to write that I don't understand why anyone would want @system-by-default until I realised that calling legacy code, including dub packages, might be a pain. Hmm.

>

Universal inference avoids these problems. In most cases, it requires zero manual intervention to migrate existing code (that is, it Just Works™). The only major obstacle it faces is build performance when using separate compilation, and this obstacle can be overcome with toolchain improvements.

I'm all for not having to write attributes the compiler can infer itself and having them "only" show up in .di files. As long as build speeds aren't affected, since it's too slow as it is for me. Do I like writing @safe @nogc pure nothrow scope const? No, but that's what I have to do right now.

May 31

On Friday, 31 May 2024 at 16:36:08 UTC, Atila Neves wrote:

>

[snip]

It wouldn't compile because of the intrinsics? Wouldn't the fix then be to add attributes to them?

Actually it may compile in this case since it looks like they already have attributes at the top of the version block for them.

I was trying to use this as an example of a file that has a mix of functions without bodies and templated functions that would have inference. It was meant as a criticism of your idea of putting @system: at the top of files as solution to the problem. As I said later in that post, putting @system: at the top would force the templated functions to be @system too instead of getting inferred. One solution is going function by function as I said in my post, but just putting it at the top isn't a solution.

May 31

On Friday, 31 May 2024 at 16:32:37 UTC, Atila Neves wrote:

>

This.

I agree my argument is not necessarily an impediment to this DIP, but it is closely related.

>

I don't think we can stop programmers intent on lying to the compiler. As mentioned there's already pragma(mangle),

Which sticks out in a review, and is clearly intentional not accidental (as I already said).

>

they can write assembly, ...

Actually that supports my case, @safe annotated asm is deprecated:
https://dlang.org/deprecate.html#unannotated%20asm%20blocks

You have to write @trusted instead, because it's not mechanically checked.

>

I think that if there's a body written in D somewhere, it's unlikely someone will manually write a declaration and use the wrong attribute by mistake. And if there isn't, then they will have had to deliberately have picked an attribute.

Not convinced it's unlikely - the implementation may be @safe when the prototype is written, then the implementation is changed to @system and the prototype is forgotten. No reason not to require @trusted for prototypes.

June 01
On 5/30/24 20:35, Atila Neves wrote:
> https://github.com/atilaneves/DIPs/blob/safe-by-default/safe-by-default.md
> 
> Destroy!

- I think even more important than the default is the ability to change the default (e.g. `default(@safe):`). This does not exist currently, but it would be required for easy migration.

- There is not really any value in being able to write `@safe extern(C)/extern(C++)` prototypes. It's wrong and any linter would need to have a warning for it. I would just require an explicit `@system` or `@trusted` annotation. Note that for `extern(C)/extern(C++)` prototypes, `@safe` and `@trusted` have _the same semantics and interpretation_, but only one of them looks adequately dangerous and is easy to grep.

- The DIP should clarify whether annotations like `@safe:` apply to prototypes or whether prototypes always need an individual annotation.

- N.B.: OpenD has been experimenting with changing the default safety level behavior to be a distinct category from the other three. (It enables checks on pointer arithmetic, but is not transitive and does not include DIP1000 checks.) It does not guarantee memory safety but can catch bugs.

June 03

On Thursday, 30 May 2024 at 18:35:36 UTC, Atila Neves wrote:

>

https://github.com/atilaneves/DIPs/blob/safe-by-default/safe-by-default.md

Destroy!

Because of a lack of mangling, extern(X) where X isn’t D shouldn’t ever be allowed to be annotated @safe unless it’s a definition.

The right way:

module a;

extern(C) int f(int) @trusted;
extern(C) int f(int) @safe; // compile error: `extern(C)` function cannot be verified `@safe`. Hint: If the implementation is written in D in another module, use `@trusted`.
module b;

extern(C) int f(int x) @safe => x; // okay: implementation present

In this case, unfortunately, @trusted can mean two things:

  • The implementation is @system, but the developer verified it is fool-proof to use UB-free.
  • The developer verified the implementation is annotated @safe. In this case, a comment can be added to indicate this case.
June 03

On Friday, 31 May 2024 at 17:45:44 UTC, jmh530 wrote:

>

On Friday, 31 May 2024 at 16:36:08 UTC, Atila Neves wrote:

>

[...]

Actually it may compile in this case since it looks like they already have attributes at the top of the version block for them.

I was trying to use this as an example of a file that has a mix of functions without bodies and templated functions that would have inference. It was meant as a criticism of your idea of putting @system: at the top of files as solution to the problem. As I said later in that post, putting @system: at the top would force the templated functions to be @system too instead of getting inferred. One solution is going function by function as I said in my post, but just putting it at the top isn't a solution.

Fair enough.