February 10, 2015
On Tuesday, 10 February 2015 at 04:18:16 UTC, Zach the Mystic wrote:
> On Tuesday, 10 February 2015 at 04:05:35 UTC, Andrei Alexandrescu wrote:
>> On 2/9/15 8:03 PM, Zach the Mystic wrote:
>>> You could put the 'trusted' template right in object.d, to save people
>>> the awkward burden of importing it from std.conv all the time. But that
>>> would be a language change, of sorts.
>>
>> We won't define it. Instead we'll go with Steve's idea: () @trusted => expr. It's not much longer and it's a teensy bit more awkward - exactly what the doctor prescribed. -- Andrei
>
> People were worried about reliable inlining, but maybe the compiler can just guarantee that somehow. Aren't we back where we were before? The only addition we were recommending is the equivalent of only allowing @trusted lambdas like the one above in @trusted and @system functions, but not in @safe ones.

Hey, why use '@system' lambdas instead? They are already banned in @safe code.
February 10, 2015
On 2/9/15 11:18 PM, Zach the Mystic wrote:
> On Tuesday, 10 February 2015 at 04:05:35 UTC, Andrei Alexandrescu wrote:
>> On 2/9/15 8:03 PM, Zach the Mystic wrote:
>>> You could put the 'trusted' template right in object.d, to save people
>>> the awkward burden of importing it from std.conv all the time. But that
>>> would be a language change, of sorts.
>>
>> We won't define it. Instead we'll go with Steve's idea: () @trusted =>
>> expr. It's not much longer and it's a teensy bit more awkward -
>> exactly what the doctor prescribed. -- Andrei
>
> People were worried about reliable inlining, but maybe the compiler can
> just guarantee that somehow. Aren't we back where we were before? The
> only addition we were recommending is the equivalent of only allowing
> @trusted lambdas like the one above in @trusted and @system functions,
> but not in @safe ones.

IIRC, gdc and ldc already do this.

This is not an issue that should dictate convention, non-inlined code does not impact correctness, only performance. And once it is fixed in the compiler, the argument would be gone, and we would be left with a convention with no good reason.

-Steve
February 10, 2015
On Tuesday, 10 February 2015 at 04:05:35 UTC, Andrei Alexandrescu wrote:
> On 2/9/15 8:03 PM, Zach the Mystic wrote:
>> You could put the 'trusted' template right in object.d, to save people
>> the awkward burden of importing it from std.conv all the time. But that
>> would be a language change, of sorts.
>
> We won't define it. Instead we'll go with Steve's idea: () @trusted => expr. It's not much longer and it's a teensy bit more awkward - exactly what the doctor prescribed. -- Andrei

Erm. This was exactly how all those trustedFoo() nested functions have appeared - we wanted to localized unsafe operations with `() @trusted {}` but it wasn't properly inlined by DMD.
February 10, 2015
On 2/10/15 12:06 AM, Dicebot wrote:
> On Tuesday, 10 February 2015 at 04:05:35 UTC, Andrei Alexandrescu wrote:
>> On 2/9/15 8:03 PM, Zach the Mystic wrote:
>>> You could put the 'trusted' template right in object.d, to save people
>>> the awkward burden of importing it from std.conv all the time. But that
>>> would be a language change, of sorts.
>>
>> We won't define it. Instead we'll go with Steve's idea: () @trusted =>
>> expr. It's not much longer and it's a teensy bit more awkward -
>> exactly what the doctor prescribed. -- Andrei
>
> Erm. This was exactly how all those trustedFoo() nested functions have
> appeared - we wanted to localized unsafe operations with `() @trusted
> {}` but it wasn't properly inlined by DMD.

Perhaps an explosion of added delegate calls will motivate people to fix it ;)

FWIW, I hate this kind of optimization based on a limitation.

-Steve
February 10, 2015
On 2/9/15 9:06 PM, Dicebot wrote:
> On Tuesday, 10 February 2015 at 04:05:35 UTC, Andrei Alexandrescu wrote:
>> On 2/9/15 8:03 PM, Zach the Mystic wrote:
>>> You could put the 'trusted' template right in object.d, to save people
>>> the awkward burden of importing it from std.conv all the time. But that
>>> would be a language change, of sorts.
>>
>> We won't define it. Instead we'll go with Steve's idea: () @trusted =>
>> expr. It's not much longer and it's a teensy bit more awkward -
>> exactly what the doctor prescribed. -- Andrei
>
> Erm. This was exactly how all those trustedFoo() nested functions have
> appeared - we wanted to localized unsafe operations with `() @trusted
> {}` but it wasn't properly inlined by DMD.

Correct. The new rules, however, prohibit using trusted code inside @safe functions. -- Andrei
February 10, 2015
On Tuesday, 10 February 2015 at 05:18:26 UTC, Andrei Alexandrescu wrote:
> On 2/9/15 9:06 PM, Dicebot wrote:
>> On Tuesday, 10 February 2015 at 04:05:35 UTC, Andrei Alexandrescu wrote:
>>> On 2/9/15 8:03 PM, Zach the Mystic wrote:
>>>> You could put the 'trusted' template right in object.d, to save people
>>>> the awkward burden of importing it from std.conv all the time. But that
>>>> would be a language change, of sorts.
>>>
>>> We won't define it. Instead we'll go with Steve's idea: () @trusted =>
>>> expr. It's not much longer and it's a teensy bit more awkward -
>>> exactly what the doctor prescribed. -- Andrei
>>
>> Erm. This was exactly how all those trustedFoo() nested functions have
>> appeared - we wanted to localized unsafe operations with `() @trusted
>> {}` but it wasn't properly inlined by DMD.
>
> Correct. The new rules, however, prohibit using trusted code inside @safe functions. -- Andrei

There's something weird going on.

H.S. Teoh's idea for @system blocks was actually an attempt to reconcile Walter's stated desire to have @trusted interfaces at the named function level with the practical need to specify precisely which code was @system and allow safety checking for all the rest. The @system blocks were originally a way to still have a use for named @trusted functions, even in the presence of specific @system blocks. But named @trusted functions become a redundancy when all @system code is precisely marked. David Nadlinger originally pointed out almost three years ago that from the caller's perspective, there is *no* difference between @safe and @trusted. They are both effectively @safe.

The only ostensible explanation for the existence of @trusted was to point a programmer who had already identified problems with memory safety to the possible locations of the unsafe code. This is arguably not a good enough reason to invent a whole new built-in function attribute, but there it is. When you mark a function @safe, you are expected to make sure it's safe. It's not really the concern of a function attribute how you made sure it was safe.

@trusted lambdas are an effective way of marking unsafe code. But they are completely pointless, at this time, unless they are placed within the context a function marked (or inferred) @safe. For them to become the idiomatic way of marking @system code, there is no further purpose to any *named* @trusted function, ever.

To preserve the (admittedly marginal) utility of named @trusted functions -- that is, the opportunity for programmers using a library which contains only the interface function signatures and a binary object file to more clearly identify which of the used functions might be causing their memory safety problems -- while also allowing safety checking of all @trusted code outside specifically marked @system blocks, would require a breaking change, as indicated in the @system blocks proposal.

Avoiding the breaking change requires using @trusted lambdas in place of @system blocks. This nullifies the original purpose of named @trusted functions, as any code which effectively uses @trusted lambdas for their intended purpose must (implicitly or explicitly) be marked @safe.

I never used the named @trusted function for its original purpose anyway. I dont' see it as a big sacrifice, but anyway, you have three choices:

1. Keep *named* @trusted functions for their original purpose, continue to rely on the programmer for manual verification of all @trusted code, and break no code. (status quo)

2. Give up on *named* @trusted functions as a lost cause, begin using @trusted lambdas to isolate all @system code, and break no code.

3. Keep named @trusted functions, introduce @system blocks to isolate @system code, and break a lot of code.

The way I see it, number 2 is the way to go, or at least the way Andrei is headed. 3 is elegant, and if I were in charge, I'd probably investigate how to make it work. 1, the status quo, is the worst, because it preserves the thing of low value (named @trustedness) at the expense of the thing of greatest value (isolating unsafe code).

I would say "destroy", but this isn't even an idea, just an analysis of the tradeoffs. So, ENJOY!
February 10, 2015
On 2/9/2015 9:06 PM, Dicebot wrote:
> This was exactly how all those trustedFoo() nested functions have appeared
> - we wanted to localized unsafe operations with `() @trusted {}` but it wasn't
> properly inlined by DMD.

DMD will inline trivial functions like that. In what case does it not?
February 10, 2015
On Tuesday, 10 February 2015 at 07:02:23 UTC, Walter Bright wrote:
> On 2/9/2015 9:06 PM, Dicebot wrote:
>> This was exactly how all those trustedFoo() nested functions have appeared
>> - we wanted to localized unsafe operations with `() @trusted {}` but it wasn't
>> properly inlined by DMD.
>
> DMD will inline trivial functions like that. In what case does it not?

import std.stdio;

void foo() @system
{
    writeln("foo");
}

void main() @safe
{
    () @trusted { foo(); } ();
}

// dmd -inline -O -g test.d

Breakpoint 1, D main () at test.d:10
10	    () @trusted { foo(); } ();
(gdb) disassemble
Dump of assembler code for function _Dmain:
   0x000000000046d3f0 <+0>:	push   %rbp
   0x000000000046d3f1 <+1>:	mov    %rsp,%rbp
=> 0x000000000046d3f4 <+4>:	callq  0x46d400 <_D4test4mainFNfZ9__lambda1FNeZv>
   0x000000000046d3f9 <+9>:	xor    %eax,%eax
   0x000000000046d3fb <+11>:	pop    %rbp
   0x000000000046d3fc <+12>:	retq
End of assembler dump.\

As you may see in generated call it actually calls lambda function (_D4test4mainFNfZ9__lambda1FNeZv) instead of calling _D4test3fooFZv directly
February 10, 2015
On Tuesday, 10 February 2015 at 04:05:35 UTC, Andrei Alexandrescu wrote:
> On 2/9/15 8:03 PM, Zach the Mystic wrote:
>> You could put the 'trusted' template right in object.d, to save people
>> the awkward burden of importing it from std.conv all the time. But that
>> would be a language change, of sorts.
>
> We won't define it. Instead we'll go with Steve's idea: () @trusted => expr. It's not much longer and it's a teensy bit more awkward - exactly what the doctor prescribed. -- Andrei

Maybe, allow @trusted @safe functions, which will
1) like @safe, disallow direct use of unsafe operations
2) unlike @safe, allow @trusted blocks
3) mostly obey @safe codegen requirements and be hopefully a little safer than plain @trusted functions
4) be reviewed as @trusted
February 10, 2015
On 2/9/2015 11:27 PM, Dicebot wrote:
> As you may see in generated call it actually calls lambda function
> (_D4test4mainFNfZ9__lambda1FNeZv) instead of calling _D4test3fooFZv directly

https://issues.dlang.org/show_bug.cgi?id=14164