DIP1028 - Rationale for accepting as is
Johannes Loher
johannes.loher at fg4f.de
Sun May 24 10:40:11 UTC 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.
More information about the Digitalmars-d-announce
mailing list