January 08, 2020
On 1/8/2020 4:12 PM, Manu wrote:
> unsafe blocks is distinctly preferable to me. Functions are usually >1
> line, and I hate that we can only mark this at the function level.
> Unsafely statements are never at the function level, it's usually just
> one line among a larger function. An unsafe scope would be immensely
> preferable to me, because I can make it as narrow as the code i'm
> suspicious of, and the surrounding code doesn't lose its safe checking
> just by being a bystander.

This is routinely done in Phobos by making a tiny one line anonymous @trusted lambda and immediately calling it. The compiler will inline it.

January 08, 2020
On 1/8/2020 4:49 PM, H. S. Teoh wrote:
> OTOH, that may be its redeeming quality: it looks so ugly, and is so
> icky to write, that it discourages people from overusing it. You're
> inclined to do it only when you absolutely have to.

Bingo!
January 08, 2020
On 1/8/2020 3:42 AM, Manu wrote:
> Whatever you reckon. I was just offering that there's an opportunity here.

I understand. But too much of this shuffling names around is just bouncing the bricks and wasting everyone's time changing their code, correcting their books, redoing websites, updating tutorials, etc., and just makes us look like dithering fools.

We've had many of these in the past. The only one that really paid off was renaming `invariant` to `immutable`, but we did that one very early before people got very far with the former.
January 09, 2020
On Thu, Jan 9, 2020 at 3:30 PM Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On 1/8/2020 4:12 PM, Manu wrote:
> > unsafe blocks is distinctly preferable to me. Functions are usually >1 line, and I hate that we can only mark this at the function level. Unsafely statements are never at the function level, it's usually just one line among a larger function. An unsafe scope would be immensely preferable to me, because I can make it as narrow as the code i'm suspicious of, and the surrounding code doesn't lose its safe checking just by being a bystander.
>
> This is routinely done in Phobos by making a tiny one line anonymous @trusted lambda and immediately calling it. The compiler will inline it.

Unacceptable and embarrassing.
The compiler does not inline it (appears to be subject to
optimisation), and LDC/GDC implement different inlining rules where
the compilers internal heuristics are undesirably perturbed by this
'pattern'.
January 09, 2020
On Wednesday, 8 January 2020 at 18:59:38 UTC, Timon Gehr wrote:
> On 08.01.20 08:10, Arine wrote:
>> 
>> @trusted doesn't really make sense. It is pretty much @system that @safe can call. It's actually kind of bad as how easily it can be misused. @trusted: comes to mind. You can have @trusted destructors. So when you are reading @safe code you can't easily tell where potentially @unsafe code is located. As the @trusted is applied to the function, not at the call site (like Rust/C#).
>> ...
>
> This line of reasoning makes no sense.
>
> @trusted void foo(T...)(T args){ ... }
>
> is like
>
> @safe void foo(T...)(T args){ unsafe{ ... } }
>
> It's the same thing. The point is that the interface of foo is assumed to safe by all callers even though the implementation might not be.

That'd be a code smell. If you have to put the entire body of a function in unsafe, that function should just be defined as unsafe. You've just given the perfect illustration of why @trusted is terrible.

>> If we are going to make @safe the default we don't really need @safe keyword, or @system or @trusted. It's make sense to get rid of all 3 of them and just add @unsafe. If you are going to do it, might as well do it right the first time.
>
> I don't care all that much either way, but let's not pretend that what you propose is different to what we have in any important way other than how convenient certain things are to express. Adding trusted statement blocks and deprecating `@trusted:` annotations would have essentially the same effect.

Did you miss the example?
January 09, 2020
On Thursday, 9 January 2020 at 00:49:29 UTC, H. S. Teoh wrote:
> On Thu, Jan 09, 2020 at 10:12:23AM +1000, Manu via Digitalmars-d wrote: [...]
>> unsafe blocks is distinctly preferable to me. Functions are usually >1 line, and I hate that we can only mark this at the function level. Unsafely statements are never at the function level, it's usually just one line among a larger function. An unsafe scope would be immensely preferable to me, because I can make it as narrow as the code i'm suspicious of, and the surrounding code doesn't lose its safe checking just by being a bystander.
>
> There is this current idiom that essentially serves as a @trusted block:
>
> 	auto myFunc() @safe {
> 		... // mundane stuff
> 		() @trusted {
> 			// dangerous stuff goes here
> 		}();
> 		... // more mundane stuff
> 	}
>
> But it's quite the eyesore, I'll admit.
>
> OTOH, that may be its redeeming quality: it looks so ugly, and is so icky to write, that it discourages people from overusing it. You're inclined to do it only when you absolutely have to.

This isn't something you'd want people to not write. It's how you are expected to write it in C# and Rust (without the lambda obviously). It makes it easier to read because you see in the @safe function what is unsafe. Creating a separate function that you probably don't need, and labeling it as @trusted just makes the code harder to read and understand what might be unsafe. You have to go through the entire function, call by call and determine which functions are unsafe.
January 09, 2020
On Thursday, 9 January 2020 at 05:37:18 UTC, Walter Bright wrote:
> On 1/8/2020 3:42 AM, Manu wrote:
>> Whatever you reckon. I was just offering that there's an opportunity here.
>
> I understand. But too much of this shuffling names around is just bouncing the bricks and wasting everyone's time changing their code, correcting their books, redoing websites, updating tutorials, etc., and just makes us look like dithering fools.

Isn't that exactly what's happening right now with changing the default to be @safe... ?


January 09, 2020
Am Thu, 09 Jan 2020 10:12:23 +1000 schrieb Manu:

> 
> unsafe blocks is distinctly preferable to me. Functions are usually >1 line, and I hate that we can only mark this at the function level. Unsafely statements are never at the function level, it's usually just one line among a larger function. An unsafe scope would be immensely preferable to me, because I can make it as narrow as the code i'm suspicious of, and the surrounding code doesn't lose its safe checking just by being a bystander.

I agree that the lambda thing is an ugly hack and proper trusted blocks would be better. However, I wonder how languages with such blocks deal with problems such as these:

@safe void someFunction()
{
    int[4] data;
    // Lot's of code
    @trusted
    {
        data.ptr[3] = 42;
    }
}

Now someone changes data to int[2]:

@safe void someFunction()
{
    int[2] data;
    // Lot's of code
    @trusted
    {
        data.ptr[3] = 42;
    }
}

So by modifying @safe code only, you introduced a memory safety issue. The interface of a @trusted function however is more strictly defined:

@trusted function set(ref int[4] data)
{
    data.ptr[3] = 42;
}

It's not possible to break the set function in @safe code. You could probably argue that the trusted block in someFunction should have covered the int[2] data definition and that you can also write @trusted functions which do not properly check / enforce their parameters and can be broken from @safe code.

But still, it seems like applying trusted/safe at function level provides stronger guarantees. I wonder how other languages deal with that? Not at all and just be extra careful when writing trusted blocks?

-- 
Johannes
January 09, 2020
On 1/9/20 1:47 PM, Johannes Pfau wrote:

> So by modifying @safe code only, you introduced a memory safety issue.

Yes, this is why a function with ANY trusted blocks must be examined completely, and changes to the non-trusted parts must be checked to see if they cause problems with the trusted blocks.

HOWEVER, it is still of tremendous value to have the rest of it mechanically checked. So I still prefer this usage to trusting the whole function.

> But still, it seems like applying trusted/safe at function level provides
> stronger guarantees. I wonder how other languages deal with that? Not at
> all and just be extra careful when writing trusted blocks?
> 

Yes, this is exactly correct. Trust must happen at the function level, because that's where you can reason about the parameters and returns. Marking it safe is not really because the function is safe, it's because marking the WHOLE function trusted is to forgo all checking inside the function, which is not what you normally want.

If we could design it again, probably you should have safe and system be what they are today, trusted would be safe, except where you put in unsafe blocks. This allows the code to pick which parts should be able to call system functions.

But I think this is digressing from the DIP discussion quite a bit. Probably best to continue if necessary in a new thread.

-Steve
January 09, 2020
On Thursday, 9 January 2020 at 18:47:23 UTC, Johannes Pfau wrote:
> Now someone changes data to int[2]:
>
> @safe void someFunction()
> {
>     int[2] data;
>     // Lot's of code
>     @trusted
>     {
>         data.ptr[3] = 42;
>     }
> }
>
> So by modifying @safe code only, you introduced a memory safety issue. The interface of a @trusted function however is more strictly defined:
>
> @trusted function set(ref int[4] data)
> {
>     data.ptr[3] = 42;
> }
>

That's a pretty contrived example.

@safe void someFunction()
{
    int[2] data;
    // Lot's of code
    @unsafe
    {
        static assert( data.length > 3 );
        data.ptr[3] = 42;
    }
}

There you get the same safety and you don't have to create a separate function that passes in a ref to a int array of a static size, that'll probably literally never be used anywhere else.

If it's a dynamic array, then they are both equally @unsafe and it's up to you to ensure it is safe. If you have that @unsafe block in the function, it's going to be a lot easier to see where that potential problem is. Otherwise it'll look like any other @safe function.