May 24, 2020
On 5/24/2020 2:29 AM, Panke wrote:
> I've always understood that the @safe,@trusted,@system machinery provides the following guarantee once all holes are fixed:
> 
> If I have a memory corruption in my code than I need to only look at the @trusted and @system parts to find it.
> 
> Marking whatevs @safe violates this, marking it @trusted does not.

It's a fair point, but without the source code the distinction is meaningless.
May 24, 2020
On Sunday, 24 May 2020 at 03:28:25 UTC, Walter Bright wrote:
> I'd like to emphasize:
> [..]

Thank you. I do see the picture now. When taking safety seriously, you would find unannotated declarations and audit/annotate them. It is not worthy of a compile option. An average user is, from experience, worse off with extern being implicitly @system.
May 24, 2020
On Sunday, 24 May 2020 at 09:47:37 UTC, Walter Bright wrote:
> On 5/24/2020 2:29 AM, Panke wrote:
>> I've always understood that the @safe,@trusted,@system machinery provides the following guarantee once all holes are fixed:
>> 
>> If I have a memory corruption in my code than I need to only look at the @trusted and @system parts to find it.
>> 
>> Marking whatevs @safe violates this, marking it @trusted does not.
>
> It's a fair point, but without the source code the distinction is meaningless.

The distinction is that you can find a slapped on trusted with a grep.
Rather than valgrind.
May 24, 2020
On Sunday, 24 May 2020 at 08:55:32 UTC, Walter Bright wrote:
> I infer your position is the idea that putting @trusted on the declarations isn't greenwashing, while @safe is.
>
> I can't see a practical difference between:
>
> @safe extern (C) void whatevs(parameters);
> @trusted extern (C) void whatevs(parameters);
>
> Both require that whatevs() provide a safe interface. The difference between them is in the implementation of those functions, not the interface. Since the D compiler cannot see those implementations, they are immaterial to the compiler and user.

From my perspective, there is a clear difference in meaning between them: @safe means verified by the compiler (which as you mentioned can never be true for declarations where the code is not available, hence it always is a lie in that case) and @trusted means verified by the developer.

Whenever @trusted is slapped on _anything_, it is clear that extra caution is needed (in codereviews etc.) and as others have mentioned, it is easily searchable.

When I put @safe on a piece of code, my expectation is that it is actually verified by the compiler. If that is not possible, it should not compile.

The same reasoning also applies to the case where the annotations are not added by the developer explicitly and the defaults are used instead:

If the default is @safe and the code for an unannotated declaration is not available, it should not compile.

Making @trusted the default is not an option because as mentioned earlier, one of the points of @trusted is for it to be actually seen, which is not the case if it is the default, so I will not elaborate on that.

If @sytem is the default, there is no issue but of course the whole point of this DIP is to move away from that.

I understand that today it is possible to slap @safe on declarations without code without the compiler complaining but it really _should_ be an error in order to have a consistent meaning of @safe, @trusted and @system (@safe = compiler verified, @trusted = user verified, @system = not verified) also in the case of declarations where no code is available.

Let's assume this is indeed the way to go, then there are 2 possible solutions for this DIP regarding how to handle this:

1. Make declarations without code default to @system instead of @safe. This is what many here have been arguing for but as you mentioned several times, it has the drawback of adding special cases to the language. As a user, it does not seem that problematic though because the compiler can easily tell you what is going on when there is an issue (i.e. calling an unannotated declaration without code from a @safe function could result in compiler error message that explains why this does not work). But I admit that it is still a bit weird to have 2 different defaults. Additionally, explicitly annotating such declarations with @safe should be a compile error.

2. Make @safe the default for _all_ declarations but still make @safe on declarations without code a compile error (because the compiler cannot verify it). This means that annotating function declarations without code with @system or @trusted is now mandatory. This is what Timon has been arguing for if I understood him correctly.

3. There may be a third option if we introduce something like conditional safety but I do not completely understand that yet. This is what H.S. Theo has been suggesting.

Option 1 and 2 both have the „issue“ that people might „greenwash“ things by simply slapping @trusted: at the top of a file. But that can always be done anyways and at least it is explicit and searchable. As mentioned, using @trusted now has the meaning that it is user verified so it always needs extra caution.

Personally I prefer option 2 because it is a lot more consistent: There are no special cases.

Until now, I did not discuss whether or not all of this should apply only to extern(C) function declarations without code or all function declarations without code. This is because it is a separate point. Both are possible and have pros and cons:

If it applies to extern(C) function declarations without code only, then we can still have @safe extern(D) declarations. They are not verified by the compiler but you get linker errors instead because @safe is part of the mangling. The benefit is that you get more @safe code by default, the drawback is that it relies on linker errors instead of compiler errors and that it introduces a special case.

If it applies to all function declarations without code, also extern(D) function declarations without bodies need to be annotated with @trusted explicitly if they are @safe or @trusted. If they are @system, we still get linker errors due to name mangling. The benefit is that it is a very consistent solution, no special cases are needed. The drawback is that it requires more manual effort to add the additional annotations (but then, don't we want to encourage people to explicitly annotate things anyways...?).

Personally, I prefer the second option because of its simplicity. Also you mentioned somewhere that linker errors are not that helpful to the user and I couldn’t agree more. Also I personally don't use extern(D) function declarations without bodies a lot, so the drawback is negligible for me. Others' experiences might be different though.

Steven actually made a proposal regarding creating 2 different manglings for extern(C) functions that are implemented in D. Regardless of which of the solutions  is taken, this could provide the same benefits that we have for extern(D) functions (linker errors if @safety does not match in the mangling). However, it sounds like a complicated solution (in an answer to him, you already mentioned that there might be technical difficulties regarding some object formats, debugging symbols, etc.) and I am not sure it's worth it. It also makes swapping out the libraries a bit weird: if you use an actual C library, it will always link but if swap to a library implemented in D, it only links if the @saftey mangling matches.


Coming back to the original point: I think it is really important that we give @safe, @trusted and @sytem their clear meaning (as explained above) also for declarations without bodies. In my opinion, we should choose the second option in both of the questions I presented.
May 24, 2020
On 24.05.20 10:55, Walter Bright wrote:
> I infer your position is the idea that putting @trusted on the declarations isn't greenwashing, while @safe is.

That's just arguing semantics. Your intended meaning of "greenwashing" is apparently slightly different from Timon's.

You can call this greenwashing:

    @trusted extern (C) void whatevs(parameters);

And this:

    @safe extern (C) void whatevs(parameters);

And then you must also call this greenwashing when compiled with `-preview=safedefault`:

    extern (C) void whatevs(parameters);

They all do the same thing.

But the first one is the most preferable form, because it shows up when you search for "@trusted" which is our "here be dragons" sign.

The second one should be deprecated in favor of the first one. That would move us one baby step closer to the ideal: "@safe code is memory safe, unless someone made a mistake with @trusted."

The third one moves us one step further away from that ideal. That's the wrong direction. It's greenwashing by default. And since greenwashing is bad, greenwashing by default means bad by default.
May 24, 2020
On Sunday, 24 May 2020 at 10:40:11 UTC, Johannes Loher wrote:
> does not work). But I admit that it is still a bit weird to have 2 different defaults.

Is that any more or less weirder than having functions inferred with different attributes based on context?

May 24, 2020
On Sunday, 24 May 2020 at 11:25:06 UTC, aliak wrote:
> On Sunday, 24 May 2020 at 10:40:11 UTC, Johannes Loher wrote:
>> does not work). But I admit that it is still a bit weird to have 2 different defaults.
>
> Is that any more or less weirder than having functions inferred with different attributes based on context?

What exactly are you referring to?
May 24, 2020
On Sunday, 24 May 2020 at 03:28:25 UTC, Walter Bright wrote:
> I'd like to emphasize:
>
> 1. It is not possible for the compiler to check any declarations where the implementation is not available. Not in D, not in any language. Declaring a declaration safe does not make it safe.
>
> 2. If un-annotated declarations cause a compile time error, it is highly likely the programmer will resort to "greenwashing" - just slapping @safe on it. I've greenwashed code. Atila has. Bruce Eckel has. We've all done it. Sometimes even for good reasons.
>
> 3. Un-annotated declarations are easily detectable in a code review.
>
> 4. Greenwashing is not easily detectable in a code review.
>
> 5. Greenwashing doesn't fix anything. The code is not safer. It's an illusion, not a guarantee.
>
> 6. If someone cares to annotate declarations, it means he has at least thought about it, because he doesn't need to. Hence it's more likely to be correct than when greenwashed.
>
> 7. D should *not* make it worthwhile for people to greenwash code.
>
> It is, in a not-at-all obvious way, safer for C declarations to default to being safe.

Apparently, you're of the opinion it's better the compiler does the greenwashing. Got it!

May 24, 2020
On Sunday, 24 May 2020 at 11:30:53 UTC, Johannes Loher wrote:
> On Sunday, 24 May 2020 at 11:25:06 UTC, aliak wrote:
>> On Sunday, 24 May 2020 at 10:40:11 UTC, Johannes Loher wrote:
>>> does not work). But I admit that it is still a bit weird to have 2 different defaults.
>>
>> Is that any more or less weirder than having functions inferred with different attributes based on context?
>
> What exactly are you referring to?

Attribute inference by D, specifically template functions. The attributes are inferred based on context (I don't know the exact algorithm). So a function f(T)(T) when called can maybe be pure, maybe safe, maybe not?
May 24, 2020
On Sunday, 24 May 2020 at 09:47:37 UTC, Walter Bright wrote:
> It's a fair point, but without the source code the distinction is meaningless.

It's meaningless in terms of what the compiler can check, but it's not meaningless in terms of documenting the assumptions and promises the developer is making.