December 14
Safer offers no guarantees of memory safety. I view it as a tool to:

1. provide some lint-like flagging of suspicious constructs

2. help educate new D users to safer practices

3. make it easier to transition to using @safe

You are an expert, and I doubt it will be of much value to you as you are already an expert in what is safe and what isn't.

Memory safety, as I predicted a few years back, is now a critical feature of a programming language, and whatever practical way we can move D in that direction we must do.
December 14
I did reply to Jonathan on that.

I put safer under a flag for the time being, in the future it should become an edition.
December 14
On 12/14/2024 7:48 AM, Timon Gehr wrote:
> Another thing is that the error messages are bad: it says "cannot do X in `@safe` function `f`", even if `f` is not a `@safe` function.

Good point.
December 14
On 12/14/24 22:36, Walter Bright wrote:
> Safer offers no guarantees of memory safety.

I am aware what it does and why.

> I view it as a tool to:
> 
> 1. provide some lint-like flagging of suspicious constructs
> 
> 2. help educate new D users to safer practices
> 
> 3. make it easier to transition to using @safe
> 
> You are an expert, and I doubt it will be of much value to you as you are already an expert in what is safe and what isn't.
> ...

Well, I sometimes use dependencies. Flagging some of the more shady things they do can be useful, and I end up forking most of them anyway. Sometimes I contribute to code bases that also have other people working on them. These goals often enough align with mine even if I am personally already an expert.

> Memory safety, as I predicted a few years back, is now a critical feature of a programming language, and whatever practical way we can move D in that direction we must do.

I agree and I am on board with the goals and also the general direction. I noted two weaknesses of this specific proposal that limit its ability to address the three goals you noted above. The more important one is that it does not apply at all to large categories of code such as templates.
December 14
On 12/14/2024 1:52 PM, Timon Gehr wrote:
> The more important one is that it does not apply at all to large categories of code such as templates.

Right. It does not apply to functions that get their attributes inferred. That includes template functions, functions that return `auto`, etc.

I haven't figured out a way to apply safer to them while still inferring attributes.
December 14
On Saturday, December 14, 2024 2:21:55 PM MST Walter Bright via Digitalmars-d wrote:
> On 12/14/2024 2:20 AM, Jonathan M Davis wrote:
> > if I actually want to do that, I can just start
> > putting @safe on my functions, and there's no need for a compiler flag.
>
> We've pushed that for years, but it doesn't work. It doesn't work because of the transitive nature of @safe - you can't do it piecemeal, it has to be done all at once.
>
> Safer is enabling the checks, but not transitively.

In general, it works just fine if you start from the bottom, since @system code can call @safe code. You do have some issues with recursion, of course, particularly when there are several functions involved, but it can be done. And of course classes have more issues with all of this in general due to how attributes interact with polymorphism. However, it's starting at the top of the call stack where it's a disaster, basically requiring @trusted everywhere as you move down the stack, whereas coming up from the bottom, it generally is quite possible to make changes in a piecemeal fashion, since it has no effect on what's up the stack if the stuff below it shifts from @system to @safe or @trusted.

The bigger problem is really that there isn't enough incentive to actually bother to mark functions @safe. Anyone who actually cared enough about @safe for a project to want to go to the effort would have been using @safe explicitly in the first place, and while @safe definitely finds problems, if you're not doing a bunch of low level stuff, it often doesn't help much in practice, so plenty of folks don't bother. And for many of those folks, @safe by default would be fine so long as the third-party code that they're calling is @safe, since they wouldn't have to use explicit attributes any more than they do now when ignoring @safe, and if they're not actually doing anything @system, then they wouldn't be doing anything for the compiler to complain about (either with @safe by default or with the flag).

In any case, I'm not against the flag existing as a helper towards moving code towards @safe by default. I just don't see enough value in it to bother using it myself, and I'm very much against the idea of ever making it the default, because without the transitivity, you don't get the actual guarantees, and you still get most of the pain.

If the flag is the default, then code in general may become more memory-safe, because folks would then be forced to either mark their code with @trusted or @system to shut the compiler up, or they'd fix the things that the flag pointed out. However, it does nothing to solve the problem of making code in general @safe or to make it easier to transition a code base to being @safe everywhere. To get the actual guarantees from @safe, the functions themselves need to also be @safe (that is, they need to be attributed as @safe by the type system), and that means either going to the effort of manually marking all of those functions with @safe (or putting @safe: at the top of the module if it has no templates), or it means having @safe by default. If you're manually marking functions as @safe, then the flag isn't helping you, and if we have @safe by default, then the flag isn't necessary (at best, it would help find issues prior to @safe becoming the default so that fewer changes need to be made at that point).

>From what I can see, having @safe by default is going to make it easier to
transition a code base to being @safe, whereas the flag will not. That's because with @safe by default, a lot of code will just magically become @safe and work, because it's not actually doing anything @system, and in many cases, the functions that it's calling will then magically become @safe as well. The code that is then doing something @system will need to be fixed, but that's true of the flag as well. So, both having the flag be the default and having @safe be the default require fixing functions which aren't explicitly marked with an attribute and which are doing something that isn't memory-safe, but with the flag, you then still have to go to all of the same effort that you'd have to go to now to explicitly mark functions with @safe or @trusted to be able to have your functions actually be @safe, whereas with @safe by default, a lot of functions gets made @safe for you.

As such, if we're going to change the default, I would strongly argue that we just make @safe the default and not the flag. @safe by default provides more benefit with less pain - at least if the ultimately goel is to have @safe functions - because then the compiler is actually helping you mark all of your functions as @safe rather than just complaining about the places where your code is doing stuff that is @system.

- Jonathan M Davis



December 15
On Saturday, 14 December 2024 at 21:36:17 UTC, Walter Bright wrote:
> Safer offers no guarantees of memory safety. I view it as a tool to:
>
> 1. provide some lint-like flagging of suspicious constructs
>
> 2. help educate new D users to safer practices
>
> 3. make it easier to transition to using @safe

If these are the goals, maybe it would make more sense for failed checks to result in warnings rather than errors.

That way, you can get the informational/educational value of -preview=safer without breaking your build, and you're only forced to satisfy the checks once you actually decide to transition to @safe.
December 14
On 12/14/2024 4:04 PM, Jonathan M Davis wrote:
> As such, if we're going to change the default, I would strongly argue that
> we just make @safe the default and not the flag.

Oh, we've tried that. It does not work. Here's the problem:

DMD has an essentially recursive nature. Every function is transitively reachable by every other function. Not 100% true, but true enough.

Enough of the code also does unsafe things like use C strings to make it just plain frustrating to try and make @safe any significant portion of it.

December 15
On 14/12/2024 9:46 PM, Walter Bright wrote:
> Now that this has been merged into master, what are your reactions?

My general view is that it could be used for migrating people to ``@safe`` by default. Would require a couple of editions to do this.

If we are not planning how to do this, I can understand the negative reactions to it.

If we are wrong about it having migratory benefits, we can always disable it and no modules in a edition would break. So I'm not seeing a down side to trying it.

If we are indeed wrong, the fact that it doesn't have an attribute (yes it could be in ``core.attribute``!) would negate any benefit it has of helping people to transition since it will not be selective.

December 15
On 15/12/2024 2:59 PM, Richard (Rikki) Andrew Cattermole wrote:
> If we are indeed wrong, the fact that it doesn't have an attribute (yes it could be in ``core.attribute``!) would negate any benefit it has of helping people to transition since it will not be selective.

I would also like to point out that this feature has a very similar behavior as another attribute that a bunch of us have been wanting for ages: ``@localnogc``.

It seems like if we want to solve this properly it is merely a matter of introducing ``@local(Identifier)`` for turning on non-transitive versions of attributes.