June 09, 2022
On Wednesday, 8 June 2022 at 23:35:03 UTC, Walter Bright wrote:
> On 6/8/2022 12:59 PM, Mathias LANG wrote:
>> I have argued with Walter for a long time that having `scope` enforced only in `@safe` code was a grave mistake, and would be extremely confusing. It would have avoided this situation.
>
> The idea is that @safe should be the default and so @system code would be rare and would stick out like a sore thumb.
>
> In @system code, maintaining the invariants of the function parameters is entirely up to the programmer.

`@safe` by default is only viable if `@safe` has minimum to no friction.
This isn't the case *at all*. We have examples in the standard library itself.

It's also departing from D's identity as a system programming language which makes it trivial to interop with C / C++, alienating a sizeable portion of our community in the process.
June 09, 2022
On Thursday, 9 June 2022 at 00:04:07 UTC, Mathias LANG wrote:
>
> `@safe` by default is only viable if `@safe` has minimum to no friction.
> This isn't the case *at all*. We have examples in the standard library itself.
>
> It's also departing from D's identity as a system programming language which makes it trivial to interop with C / C++, alienating a sizeable portion of our community in the process.

It does seem to me, that there is greater move towards memory safety 'by default', and not away from it.

Rust has demonstrated, that this is not antithetical to systems programming.

Unsafe is always available when it's required.

But yes, certainly, @safe needs a lot more work for it to ever be considered as a default in D. I have it as default in every module I create. I usually have to end up commenting it out, even for simple things.

But IMO, in programming, one should be moving towards being explicit about being unsafe, rather than being safe.

Those who are truly alienated by such an idea, have C/C++ ;-)

June 09, 2022
On 09.06.22 01:19, Walter Bright wrote:
> On 6/8/2022 10:50 AM, John Colvin wrote:
>> The problem is `foo` and whether the compiler should somehow prevent the inconsistency between the signature and implementation. Obviously the answer is “yes, ideally”, but in practice with @safe, @system, dip1000, @live and so on it’s all a mess.
> 
> The checks aren't done for @system code. Yes, the compiler believes you for @system code. It's the point of @system code.
> 
> If foo() is annotated with @safe,
> 
>    test6.d(5): Deprecation: scope variable `s` may not be returned
> 
> The compiler is working as intended, this is not unexpected behavior.

Actually it *is* unexpected behavior.

```d

int* foo()@system{
    int x;
    return &x; // error
}

int* foo(ref int x)@system{
    return &x; // error
}

int* foo(scope int* x)@system{
    return x; // ok
}
```

This does not have anything to do with `@safe` by default, it's just an inconsistency in the compiler implementation.
June 08, 2022
On 6/8/22 16:47, H. S. Teoh wrote:

> @safe by default is a good thing to have

I think we used wrong names. @safe is not safe because it allows an escape hatch. Today, @safe is actually "trusted" because the compiler trusts the programmer but checks whatever it is allowed to. Basically today's @safe is "verify, but trust".

> -- except on
> extern(C) interfaces to C code, which by definition is un-@safe

I see it differently: extern(C) interfaces are @trusted but they can't be checked. (More below.)

I was convinced (after having an email exchange with Walter) that unless we assumed extern(C) functions @safe, then nobody would bother marking their declarations as @trusted one-by-one. And whoever marked them as such, they would do it without actually auditing any source code.

What have we gained by disapproving @safe-by-default? Nothing: C API would either not be called and be marked blindly as @trusted. I think this is more embarrassing than @safe-by-default C libraries.

So, D's presumed embarrassment of "C functions are assumed @safe" was against both practicality and the truth: The truth is, we indeed "trust" C functions because we use C libraries all the time without reading their source code. This is the definition of trust. And that's why I say we chose wrong names around this topic.

> -- the
> most it can be is @trusted, and I'm sure nobody wants @trusted by
> default.)

Me wants @trusted by default but with some semantic changes! :)

I think I have written the following proposal before, which requires changing the semantics but I haven't thought about every detail. (I am not methodic nor complete when it comes to such design ideas.)

So, this is what we have currently:

  @safe: Checked with escape hatch

  @trusted: Assumed safe, unchecked

  @system: Assumed unsafe, unchecked

  default: @system

  extern(C): @system

The whole thing could have started (and I believe can be changed into) like the following instead:

  @safe: Checked without escape hatch

  @trusted: Checked, with escape hatch (@system will be the escape hatch)

  @system: Assumed unsafe, unchecked

  default: @trusted

  extern(C): @trusted but can't check

As that list may be hard to parse, here is a commentary:

@safe: We had it wrong. @safe should mean "safe" without any escape hatch.

@trusted: The name was fine but why not check D code that is not marked? So, let's make this the default, and check all D code. Everybody will benefit. Except, we will have to add @system{} to some places.

@system: No change here but this becomes the escape hatch.

extern(C): We will happily call them from @trusted code (but not @safe code) but we can't check them. So what? The society trusts C libraries, so do we.

Ali

June 09, 2022
On 09.06.22 02:44, Ali Çehreli wrote:
> The society trusts C libraries, so do we.

free(cast(void*)0xDEADBEEF)

Seems legit.
June 09, 2022
On 09.06.22 02:54, Timon Gehr wrote:
> On 09.06.22 02:44, Ali Çehreli wrote:
>> The society trusts C libraries, so do we.
> 
> free(cast(void*)0xDEADBEEF)
> 
> Seems legit.

I guess this does not actually make the point very well. Second try:

```d
free(new int);
```

Seems legit. The C library can do no wrong!
June 08, 2022
OOn 6/8/22 17:54, Timon Gehr wrote:
> On 09.06.22 02:44, Ali Çehreli wrote:
>> The society trusts C libraries, so do we.
>
> free(cast(void*)0xDEADBEEF)
>
> Seems legit.

I don't get the point. The society uses C libraries in many places. I assume many important libraries like libssh are written in C.

If your point was about my proposal, I meant only @trusted code would be able to call a C library. So, if your expression above was in D code, then the compiler would reject it (@trusted-by-default but @trusted is checked). The programmer would have to mark it as @system.

Ali

June 09, 2022
On Thursday, 9 June 2022 at 00:44:58 UTC, Ali Çehreli wrote:
>
> .... So, this is what we have currently:
>
>   @safe: Checked with escape hatch
>
>   @trusted: Assumed safe, unchecked
>
>   @system: Assumed unsafe, unchecked
>
>   default: @system
>
>   extern(C): @system
> ....


and people complain about the extra cognitive load associated with my idea of 'private (this) int x;'

All these attributes you mention, wanna make my head explode ;-)

June 08, 2022
On 6/8/22 18:04, Timon Gehr wrote:
> On 09.06.22 02:54, Timon Gehr wrote:
>> On 09.06.22 02:44, Ali Çehreli wrote:
>>> The society trusts C libraries, so do we.
>>
>> free(cast(void*)0xDEADBEEF)
>>
>> Seems legit.
>
> I guess this does not actually make the point very well. Second try:
>
> ```d
> free(new int);
> ```
>
> Seems legit. The C library can do no wrong!

I still don't get it. :(

That mistake has nothing to do with the C library. If your object is to @trusted code being able to call free, then no special marking can be practically useful. Forcing D code to be @system just to call free() is counter productive because the D code does not get checked.

When D code is @trustet, at least situation like my other response would be caught by D.

I mean, who wins by @system-by-default? Nobody. The code is not safer.

Ali

June 08, 2022

On 6/8/22 7:31 PM, Walter Bright wrote:

>

On 6/8/2022 12:02 PM, Steven Schveighoffer wrote:

>

But for some reason,

The reason is it's @system code, where it's on the programmer.

@safe layers on a vast smorgasbord of extra checking.

I'll respond basically to all your points here.

  1. Yes, I get that this is @system code, and it appears that returning of scope data in @system code is obviously subject to memory corruption. For some reason, while you can't return a pointer to a local, you can return a scope pointer.
  2. The programmer is not expecting this. They did not write scope, they wrote in, which according to the spec is "equivalent to const" (see https://dlang.org/spec/function.html#in-params). I'm convinced that we absolutely cannot turn on preview in by default until this is addressed. I can't even recommend using the preview switch, as this is too dangerous for memory safety.
  3. The safe by default DIP (as everyone else has mentioned) was great, except for extern(C) functions. I believe a vast majority wanted it without that poison pill.

-Steve