Jump to page: 1 28  
Page
Thread overview
Encapsulating trust
Aug 31, 2014
Dmitry Olshansky
Aug 31, 2014
monarch_dodra
Sep 01, 2014
ketmar
Sep 01, 2014
Dmitry Olshansky
Sep 01, 2014
monarch_dodra
Sep 01, 2014
Dicebot
Sep 01, 2014
Daniel Murphy
Sep 01, 2014
monarch_dodra
Sep 01, 2014
Dicebot
Sep 01, 2014
monarch_dodra
Sep 01, 2014
Daniel Murphy
Sep 01, 2014
Dicebot
Sep 01, 2014
Daniel Murphy
Sep 02, 2014
Dmitry Olshansky
Sep 02, 2014
Daniel Murphy
Sep 01, 2014
Denis Shelomovskij
Sep 02, 2014
Walter Bright
Sep 02, 2014
ketmar
Sep 02, 2014
Dicebot
Sep 02, 2014
ketmar
Sep 02, 2014
Dicebot
Sep 02, 2014
ketmar
Sep 02, 2014
bearophile
Sep 02, 2014
ketmar
Sep 02, 2014
Dicebot
Sep 02, 2014
ketmar
Sep 02, 2014
Andrew Godfrey
Sep 02, 2014
ketmar
Sep 02, 2014
ketmar
Sep 02, 2014
ketmar
Sep 02, 2014
ketmar
Sep 03, 2014
ketmar
Sep 03, 2014
ketmar
Sep 03, 2014
ketmar
Sep 02, 2014
ketmar
Sep 02, 2014
Paulo Pinto
Sep 02, 2014
ketmar
Sep 02, 2014
Paulo Pinto
Sep 02, 2014
ketmar
Sep 02, 2014
Marc Schütz
Sep 02, 2014
ketmar
Sep 02, 2014
ketmar
Sep 02, 2014
Paulo Pinto
Sep 02, 2014
ketmar
Sep 02, 2014
Paulo Pinto
Sep 02, 2014
bearophile
Sep 02, 2014
Dmitry Olshansky
Sep 02, 2014
Marc Schütz
Sep 02, 2014
Daniel Murphy
Sep 02, 2014
Dmitry Olshansky
Sep 02, 2014
Daniel Murphy
Sep 02, 2014
Walter Bright
Sep 02, 2014
Walter Bright
Sep 02, 2014
Dmitry Olshansky
Sep 02, 2014
monarch_dodra
Sep 02, 2014
Daniel Murphy
Sep 02, 2014
monarch_dodra
Sep 02, 2014
Walter Bright
Sep 02, 2014
Dmitry Olshansky
Sep 02, 2014
Walter Bright
Sep 02, 2014
David Nadlinger
Sep 03, 2014
deadalnix
Sep 03, 2014
Iain Buclaw
Sep 03, 2014
deadalnix
Sep 03, 2014
David Nadlinger
Sep 03, 2014
Iain Buclaw
August 31, 2014
Quite recently a lot of work has been done to make most of Phobos usable in @safe code.

While a very welcome effort, it caused a number of doubts in particular due to the boilerplate required to isolate a small amount of unsafe operations and slap "@trusted" over it.

See e.g. Denis argument:
https://github.com/D-Programming-Language/phobos/pull/2465

There were proposals for language changes along the lines of having @trusted block alike to debug/version blocks, but nothing ever came out of them.

Without language support I decided it worth a shot to create a universal wrappers to establish a consistent convention. A use of such wrapper should indicate that a @system function call or language feature was hand-verified.

Names and complete set of primitives are up for debate, but here is the start:

https://gist.github.com/DmitryOlshansky/bc02f369c8a63818bd07

A bit of usage:

import core.stdc.string;
import trusted;

void main() @safe
{

    char[] msg = "Hello!".dup;
    char[] msg2 = msg;
    import trusted; // may also use static import for absolute clarity
    assert(call!memcmp(addrOf(msg[0]), addrOf(msg2[0]), msg.length) == 0);
}


What do you guys think?

-- 
Dmitry Olshansky
August 31, 2014
On Sunday, 31 August 2014 at 13:47:42 UTC, Dmitry Olshansky wrote:
> What do you guys think?

I'd say add "trusted" to those function names:
"trustedCall"
"trustedAddrOf"

Because:
- "call" could mean a lot of things. It's not imidiatly obvious that it is meant for being trusted.
- "addrOf" is *also* used as an alternative for "&", especially in generic code, when you need the address of an attribute, as that attribute could actually be a property function. EG:
auto p = addrOf(r.front);
Nothing here implies trust.

Also, implementation wise, wouldn't it be possible to instead make `call` a template aliases itself away to `fun`, but with different attributes? The `auto fun(Args)(auto ref Args args)` tube approach has the disadvantages that it:
- prevents return by ref
- fails perfect forwarding of lvalues into rvalues.
September 01, 2014
On Sun, 31 Aug 2014 20:36:59 +0000
monarch_dodra via Digitalmars-d <digitalmars-d@puremagic.com> wrote:

> On Sunday, 31 August 2014 at 13:47:42 UTC, Dmitry Olshansky wrote:
> > What do you guys think?
> 
> I'd say add "trusted" to those function names:
> "trustedCall"
> "trustedAddrOf"
i first think like this too, but then i remembered that "call" is in module "trusted", so one who can document the code is free to write "trusted.call". and one who want something short can use simple "call".


September 01, 2014
01-Sep-2014 00:36, monarch_dodra пишет:
> On Sunday, 31 August 2014 at 13:47:42 UTC, Dmitry Olshansky wrote:
>> What do you guys think?
>
> I'd say add "trusted" to those function names:
> "trustedCall"
> "trustedAddrOf"
>

Would we ever use our module system? I agree though that being easily grep-able is useful for these functions.

assumeSafe?

> Because:
> - "call" could mean a lot of things. It's not imidiatly obvious that it
> is meant for being trusted.
> - "addrOf" is *also* used as an alternative for "&", especially in
> generic code, when you need the address of an attribute, as that
> attribute could actually be a property function. EG:
> auto p = addrOf(r.front);
> Nothing here implies trust.

Local import of 'trusted' right there might imply trust. Selective, preferably static.

>
> Also, implementation wise, wouldn't it be possible to instead make
> `call` a template aliases itself away to `fun`, but with different
> attributes? The `auto fun(Args)(auto ref Args args)` tube approach has
> the disadvantages that it:
> - prevents return by ref

auto ref return FTW

> - fails perfect forwarding of lvalues into rvalues.

?

void inc(ref int a)
{
    a += 1;
}
    int b;
    call!inc(b);
    assert(b == 1);

Works fine.

-- 
Dmitry Olshansky
September 01, 2014
On Monday, 1 September 2014 at 07:13:47 UTC, Dmitry Olshansky wrote:
>
> auto ref return FTW

I thought you had avoided that on purpose, in the sense that generic auto-ref input *and* output has been proven unsafe, in the sense that there are tons of ways for the compiler to accidently return a ref to something that is actually local.

unaryFun!"a[0]" or unaryFun"a.field" is a perfect example of that.
Or, say:
int tube(int a){return a;}
ref int tube(ref int a){return a;}
call!tube(5); //Here

>> - fails perfect forwarding of lvalues into rvalues.
>
> ?
>
> void inc(ref int a)
> {
>     a += 1;
> }
>     int b;
>     call!inc(b);
>     assert(b == 1);
>
> Works fine.

Yes, but:
call!inc(5) will *also* succeed.

But background on this issue would be certain functions, such as "emplace" that could elide postblit entirely when asked to emplace from an rvalue. The issue is that such functions that use auto-ref have a tendency to lose that information.

We could use "std.algorithm.forward", but that function is currently too expensive.

That said, there are no real functions that would exploit this "perfect forwarding" anyways. I filed:
https://issues.dlang.org/show_bug.cgi?id=12683
https://issues.dlang.org/show_bug.cgi?id=12684
After Andrei filed:
https://issues.dlang.org/show_bug.cgi?id=12628

Which would be the first steps to really start making more efficient use of rvalues in D.
September 01, 2014
I am not convinced it warrants dedicated helper as opposed to just fixing compiler to inline those lambdas.
September 01, 2014
"Dmitry Olshansky"  wrote in message news:ltv91u$2mtc$1@digitalmars.com...

> Quite recently a lot of work has been done to make most of Phobos usable in @safe code.
>
> While a very welcome effort, it caused a number of doubts in particular due to the boilerplate required to isolate a small amount of unsafe operations and slap "@trusted" over it.
>
> See e.g. Denis argument:
> https://github.com/D-Programming-Language/phobos/pull/2465
>
> There were proposals for language changes along the lines of having @trusted block alike to debug/version blocks, but nothing ever came out of them.
>
> Without language support I decided it worth a shot to create a universal wrappers to establish a consistent convention. A use of such wrapper should indicate that a @system function call or language feature was hand-verified.
>

>
> What do you guys think?

I think this is an abuse of @trusted.  It takes unsafe operations, and re-presents them as @safe options by renaming them.  Now, you can do use @system things in @safe functions without the compiler detecting it.

Take the `addrOf` function for example.  This is equivalent to adding a new version of the '&' operation, which does exactly the same thing except it's allowed in @safe code.  The `addrOf` function should _not_ be @trusted, because when used from @safe code it can cause escape the address of a local etc, just like '&' can.

Because these functions violate the meaning of @trusted, that @trusted functions must be @safe although the compiler can't prove them @safe, you've increased the surface of @trusted.  Now an audit of @trusted code must include all functions that call `addrOf` and friends.

I don't think this is a good idea.  Each time @trusted is used, it should be on a function that is completely @safe to call.  I think this is worth more than the cost in verbosity.

Lambdas and nested functions are special in that they can't be called from other code, so they only have to be @safe in the context of the enclosing function.  They do still need to make sure they don't violate @safe, otherwise the entire enclosing function will need to be manually checked.

eg
void fun(int a) @safe
{
...
   p = @trusted () { return &a; }
...
}

This function is now essentially @trusted, because although the unsafe '&' operation was inside the trusted block, the @safe function now has a pointer it should not have been able to get. 

September 01, 2014
On Monday, 1 September 2014 at 16:36:04 UTC, Daniel Murphy wrote:
> I don't think this is a good idea.  Each time @trusted is used, it should be on a function that is completely @safe to call.  I think this is worth more than the cost in verbosity.
>
> Lambdas and nested functions are special in that they can't be called from other code, so they only have to be @safe in the context of the enclosing function.  They do still need to make sure they don't violate @safe, otherwise the entire enclosing function will need to be manually checked.
>
> eg
> void fun(int a) @safe
> {
> ...
>    p = @trusted () { return &a; }
> ...
> }
>
> This function is now essentially @trusted, because although the unsafe '&' operation was inside the trusted block, the @safe function now has a pointer it should not have been able to get.

I feels like you are missing the point of the @trusted lambda construct, in that is meant to be used in generic code, where you know a *piece* of a function is provably safe (eg: @trusted), but not all of it: The rest of the code depends on the inferred attributes of the parameter-dependent code.

If your function is not generic, then just mark it as @trusted, and then that's that.

Another alternative I had proposed was one of being able to simply create blocks with attributes. EG:

void foo(T)(T t)
{
    t.doSomething(); //May or may not be safe.

    nothrow
    {
        ... //Do "critical" code that can't throw here.
    }

    @trusted
    {
        ... //This slice of code is trusted.
    }

    @safe @nogc
    {
        ... //Have the compiler enforce only @safe and @ngc code goes here.
    }
    return t;
}
September 01, 2014
On Monday, 1 September 2014 at 17:48:59 UTC, monarch_dodra wrote:
> I feels like you are missing the point of the @trusted lambda construct, in that is meant to be used in generic code, where you know a *piece* of a function is provably safe (eg: @trusted), but not all of it: The rest of the code depends on the inferred attributes of the parameter-dependent code.
>
> If your function is not generic, then just mark it as @trusted, and then that's that.

I totally disagree. Marking whole function @trusted (unless those are extern(C)) is an abomination we should try to get rid of. Trusted lambda must encapsulate minimal amount of code possible together with all data validation if necessary.Anything else simply does not scale with maintenance and is likely to introduce holes in @safe.
September 01, 2014
On Monday, 1 September 2014 at 17:59:07 UTC, Dicebot wrote:
> On Monday, 1 September 2014 at 17:48:59 UTC, monarch_dodra wrote:
>> I feels like you are missing the point of the @trusted lambda construct, in that is meant to be used in generic code, where you know a *piece* of a function is provably safe (eg: @trusted), but not all of it: The rest of the code depends on the inferred attributes of the parameter-dependent code.
>>
>> If your function is not generic, then just mark it as @trusted, and then that's that.
>
> I totally disagree. Marking whole function @trusted (unless those are extern(C)) is an abomination we should try to get rid of. Trusted lambda must encapsulate minimal amount of code possible together with all data validation if necessary.Anything else simply does not scale with maintenance and is likely to introduce holes in @safe.

I meant it mostly in that the proposal to mark the entire function as @trusted isn't even *applicable* to template functions.

I agree with you.
« First   ‹ Prev
1 2 3 4 5 6 7 8