February 07, 2015
On Friday, 6 February 2015 at 21:08:21 UTC, Walter Bright wrote:
> 1. exceptions are not for debugging the logic of your program
> 2. do not use exceptions to recover from logic bugs in your program

OK, this is nothing new, but still doesn't answer my question.

Would you say that the correct thing to do, then, would be an unconditional check that throws an Error? Such as, `if (!...) throw new Error(...)`, or `enforce!Error(...)`?

I recall there is a bug report on Bugzilla that Phobos contracts are removed in release (default) builds of the library, when ideally contracts of public functions should stay but inner asserts should be removed in optimized code. That would allow using them for validating parameters without resorting to explicitly-unconditional checks.
February 07, 2015
On Saturday, 7 February 2015 at 01:43:01 UTC, Andrei Alexandrescu wrote:
> With the system proposal we're looking at something like:
>
> version (Posix) void[] read(in char[] name, size_t upTo = size_t.max) @trusted
> {
>     import core.memory;
>     // A few internal configuration parameters {
>     enum size_t
>         minInitialAlloc = 1024 * 4,
>         maxInitialAlloc = size_t.max / 2,
>         sizeIncrement = 1024 * 16,
>         maxSlackMemoryAllowed = 1024;
>     // }
>
>     @system
>     {
>         immutable fd = core.sys.posix.fcntl.open(name.tempCString(),
>             core.sys.posix.fcntl.O_RDONLY);
>     }
>     cenforce(fd != -1, name);
>     scope(exit) core.sys.posix.unistd.close(fd);
>
>     stat_t statbuf = void;
>     @system
>     {
>         cenforce(trustedFstat(fd, trustedRef(statbuf)) == 0, name);
>     }
>
>     immutable initialAlloc = to!size_t(statbuf.st_size
>         ? min(statbuf.st_size + 1, maxInitialAlloc)
>         : minInitialAlloc);
>     void[] result = uninitializedArray!(ubyte[])(initialAlloc);
>     scope(failure) delete result;
>     size_t size = 0;
>
>     for (;;)
>     {
>         @system
>         {
>             immutable actual = core.sys.posix.unistd.read(fd, result.ptr + size),
>                 min(result.length, upTo) - size);
>         }
>         cenforce(actual != -1, name);
>         if (actual == 0) break;
>         size += actual;
>         if (size < result.length) continue;
>         immutable newAlloc = size + sizeIncrement;
>         @system
>         {
>             result = GC.realloc(result.ptr, newAlloc, GC.BlkAttr.NO_SCAN)[0 .. newAlloc];
>         }
>
>     @system
>     {
>         return result.length - size >= maxSlackMemoryAllowed
>             ? GC.realloc(result.ptr, size, GC.BlkAttr.NO_SCAN)[0 .. size]
>             : result[0 .. size];
>     }
> }
>
> We want to move D forward, folks. This is not it.
>
>
> Andrei

Oh I see. There are three posts, in the latter two of which the little @trusted functions are already removed. I had thought they were all identical, but you obviously realized the little functions should be removed.
February 07, 2015
On 2/6/2015 9:49 PM, Vladimir Panteleev wrote:
> On Friday, 6 February 2015 at 21:08:21 UTC, Walter Bright wrote:
>> 1. exceptions are not for debugging the logic of your program
>> 2. do not use exceptions to recover from logic bugs in your program
>
> OK, this is nothing new, but still doesn't answer my question.

You wrote "is clearly a program bug". Therefore use assert(). It's as simple as that.

February 07, 2015
On Saturday, 7 February 2015 at 00:31:41 UTC, H. S. Teoh wrote:
> This does not take into the account the fact that a @trusted function
> may call other, non-@trusted, functions. When one of those other
> functions changes, the @trusted function necessarily needs to be
> reviewed again.
>
> However, under the current implementation, this is not done because when
> the other, non-@trusted, function is modified, nobody thinks to
> re-review the @trusted function. They may not even be in the same
> module. There is no mechanism in place to raise a warning flag when a
> @trusted function's dependencies are modified. Thus, the proof of safety
> of the @trusted function has been invalidated, but trust continues to be
> conferred upon it.

So what you should ask for is a way to "sign" @trusted with a timestamp that indicates when it was last proven to be safe, e.g.: @trusted("2015-01-01T12:30:12z")

Then ask for a fine grained dependency tracking tool that can extract changes from git. Such a dependency tracking tool could be a nice stepping stone for faster compilation (sub-file-level recompilation). So there is synergies in this.

The proposal to confuse @trusted/@safe with requiring @system within @trusted it not a language issue. It is a process issue and can be done with lint-like tooling.

Keep @trusted/@safe/@system simple. Enough convoluted semantics in D already.

February 07, 2015
On Thursday, 5 February 2015 at 23:39:39 UTC, Walter Bright wrote:
> The solution is to regard @trusted as a means of encapsulating unsafe operations, not escaping them. Encapsulating them means that the interface from the @trusted code is such that it is usable from safe code without having to manually review the safe code for memory safety. For example (also from std.array):
>
>   static void trustedMemcopy(T[] dest, T[] src) @trusted
>   {
>     assert(src.length == dest.length);
>     memcpy(dest.ptr, src.ptr, src.length * T.sizeof);
>   }
>
> I don't have to review callers of trustedMemory() because it encapsulates an unsafe operation (memcpy) with a safe interface.

If I understand correctly, your rule o be a trusted function is:
"Unable to create a memory corrutpion whatever the arguments".

But here:
- dest or src could be the null slice
- the assert would go away in release

So I though this example _could_ corrupt memory?



>
> The reason @trusted applies only to functions, and not to blocks of code, is that functions are the construct in D that provides an interface. Arbitrary blocks of code do not have a structured interface. Adding @trusted { code } support will encourage incorrect uses like the opening example. The existence of @trusted blocks will require review of every line of code in the function that encloses it, and transitively every function that calls it!
>
> Adding @trusted as a function attribute, on the other hand, only requires review of the function's interface to determine if it is acceptable to use in safe code. Safety review of its callers is unnecessary.

February 07, 2015
On Saturday, 7 February 2015 at 10:02:23 UTC, ponce wrote:
> If I understand correctly, your rule o be a trusted function is:
> "Unable to create a memory corrutpion whatever the arguments".
>
> But here:
> - dest or src could be the null slice
> - the assert would go away in release
>
> So I though this example _could_ corrupt memory?
>

I see know it was already addressed:
http://forum.dlang.org/post/mb1vmt$etn$1@digitalmars.com
February 07, 2015
On 2/6/15 4:36 PM, "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= <ola.fosheim.grostad+dlang@gmail.com>" wrote:
> On Friday, 6 February 2015 at 20:13:18 UTC, Steven Schveighoffer wrote:
>> In the proposal, @trusted code is actually considered the same as
>> @safe, but allows @system escapes.
>
> But that can't work:
>
> @trusted_is_safe {
>
>    auto tmp = get_hardware_config();
>
>    @system{
>      mess_up_hardware_config();
>    }
>
>    // now this unsafe call is called in a @safe context, but is unsafe...
>    // DMD does not catch this, so "@trusted_is_safe" is broken
>
>    call_safe_code_that_now_is_messed_up();
>
>    @system{
>       restore_hardware_config(tmp);
>    }
> }

The idea is that @trusted code still has to be reviewed for memory issues, but is mechanically checked for most of the function for obvious @safe violations. It limits to a degree the scrutiny one must apply to the @trusted function.

Remember, the whole point of a @trusted function is that it's manually verified.

-Steve

February 07, 2015
On 2/6/15 5:19 PM, Meta wrote:
> On Friday, 6 February 2015 at 20:13:18 UTC, Steven Schveighoffer wrote:
>> In the proposal, @trusted code is actually considered the same as
>> @safe, but allows @system escapes.
>
> That seems like a good idea and in the spirit of what the goal is.
> However, won't it be a breaking change?
>

Yes. The big question is, is it worth it? I would say yes, since @trusted is already incorrectly used in most cases.

-Steve
February 07, 2015
On Saturday, 7 February 2015 at 06:20:16 UTC, Walter Bright wrote:
> On 2/6/2015 9:49 PM, Vladimir Panteleev wrote:
>> On Friday, 6 February 2015 at 21:08:21 UTC, Walter Bright wrote:
>>> 1. exceptions are not for debugging the logic of your program
>>> 2. do not use exceptions to recover from logic bugs in your program
>>
>> OK, this is nothing new, but still doesn't answer my question.
>
> You wrote "is clearly a program bug". Therefore use assert(). It's as simple as that.

OK, thank you. A few years ago you were recommending something else for this situation. We were in disagreement then, and I agree with your current opinion.
February 07, 2015
On Saturday, 7 February 2015 at 11:32:41 UTC, Steven Schveighoffer wrote:
> The idea is that @trusted code still has to be reviewed for memory issues, but is mechanically checked for most of the function for obvious @safe violations. It limits to a degree the scrutiny one must apply to the @trusted function.
>
> Remember, the whole point of a @trusted function is that it's manually verified.

This is the wrong way to do it and this is a tooling issue, not a language issue.


The right way to do it is this:

1. annotate the @trusted region manually where it is needed

2. mechanically verify the whole @trusted region

Of course, then you also need a theorem prover...



You are trying to do this:

1. mechanically verify the whole @trusted region

2. manually verify the whole @trusted region, but be sloppy about it here an there

3. Ooops, we were sloppy in the wrong spot...


Not good.