November 06, 2009
On Thu, 05 Nov 2009 16:40:11 -0500, Adam D. Ruppe <destructionator@gmail.com> wrote:

> On Thu, Nov 05, 2009 at 10:19:27PM +0100, Ary Borenszweig wrote:
>> I don't want to think about
>> safety all the time, just let me code! If something is unsafe I'll mark
>> it for you, compiler, no problem, but do you think I'm just some crazy
>> unsafe maniac? I program safely.
>
> This might be a problem. If safe functions can only call other safe functions
> and all functions are safe by default, unsafe becomes viral.
>
> Let me give an example:
>
> void main() {
>   doSomething();
>   doSomethingElse();
> }
>
> void doSomething() { does safe things }
> void doSomethingElse() { oneMoreFunction(); }
>
> void oneMoreFunction() { byte* a = cast(byte*) 0xb80000000L; // unsafe!}
>
>
> Now, to actually call oneMoreFunction, you have to mark it as unsafe. Then,
> since it is called in doSomethingElse, you have to mark it as unsafe. Then,
> since it is called from main, it too must be marked unsafe.
>
> This would just get annoying.
>
>
> This is bypassed by marking oneMoreFunction() as @trusted. Having an @unsafe
> is unworkable in safe by default. It is just default (safe) and marked
> (trusted).
>
>
>
> Which is going to work best for existing code? With Walter's idea, you
> compile it, then fix functions piece by piece to make them safe. Since your
> other unsafe functions can still call them, the change is localized and you
> get safer with each revision.
>
> With safe by default, you'd probably make existing code compile just by
> slapping @trusted: at the top and being done with it. That's not actually
> safe - you're just telling the compiler to shut up about it.
>
>

Right. Pure propagates toward callees. C++'s const member functions propagate towards callees. I think we should use safe since it too propagates toward callees. Having safe be default would cause an unsafe attribute to propagate back toward callers, which seems backwards.
November 06, 2009
On Thu, 05 Nov 2009 17:11:38 -0500, Walter Bright <newshound1@digitalmars.com> wrote:

> dsimcha wrote:
>> Ok, I understand the basic principle of a reap, but if it's going to convert to a
>> heap when you try to delete something, why not just improve the standard GC heap,
>> i.e. by making per-thread heaps?
>
> The problem with per-thread heaps is immutable data can be passed between threads.

I always assumed that with thread local heaps, both immutable and shared data would be allocated from a shared heap. Also, the shared heap should use some form of thread local allocation.
November 06, 2009
Walter Bright, el  5 de noviembre a las 12:12 me escribiste:
> Steven Schveighoffer wrote:
> >If unsafe means you cannot pass pointers to local variables, then half of tango (and other performance oriented libs which use stack allocation as much as possible) will fail to compile.
> >
> >My vote is for unsafe as the default.  It's the least intrusive option, to ensure that current projects still compile.  Then let the project authors ensure their projects are safe one module/function at a time.
> 
> I agree. Also, dealing with safeness is something that comes later on as a project scales to a larger size. As such, it's more of a nuisance on a small program than a help.
> 
> >Also keep in mind that @safe annotations for a mostly safe project will be once at the top of each module.  They won't be "everywhere".
> 
> Right. Adding:
> 
>    @safe:
> 
> at the top will do it.

Being so easy to mark a whole file unsafe, I think safe as default is
a saner choice. It add an interesting property of Cardelli's definition:
no untrapped errors. People by default will be warned about any unsafe
behaviour, if you really want unsafe, just say so.

-- 
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
<Damian_Des> Me anDa MaL eL CaPSLoCK
November 06, 2009
Walter Bright wrote:
>> Well, if that's a problem you could fix it by making immutable not shared unless you also put the shared attribute:
>>
>>     immutable Object o;        // thread-local
>>     shared immutable Object o; // visible from all threads
> 
> 
> Aaggghhhh !!! <g>
> 

ditto
November 06, 2009
Walter Bright wrote:
> Andrei Alexandrescu wrote:
>> Walter Bright wrote:
>>> Jason House wrote:
>>>> I posted in the other thread how casting to immutable/shared can be
>>>> just as bad. A leaked reference prior to casting to immutable/shared
>>>> is in effect the same as casting away shared. No matter how you mix
>>>> thread local and shared, or mutable and immutable, you still have the
>>>> same undefined behavior
>>>
>>> Not undefined, it's just that the compiler can't prove it's defined behavior. Hence, such code would go into a trusted function.
>>
>> Are we in agreement that @safe functions have bounds checking on regardless of -release?
> 
> You're right from a theoretical perspective, but not from a practical one. People ought to be able to flip on 'safe' without large performance penalties.
> 
> If it came with inescapable large performance penalties, then it'll get a bad rap and people will be reluctant to use it, defeating its purpose.

This is a showstopper.

What kind of reputation do you think D would achieve if "safe" code has buffer overrun attacks?

A function that wants to rely on hand-made verification in lieu of bounds checks may go with @trusted. There is absolutely no way a @safe function could allow buffer overruns in D, ever.


Andrei
November 06, 2009
Adam D. Ruppe, el  5 de noviembre a las 16:40 me escribiste:
> With safe by default, you'd probably make existing code compile just by slapping @trusted: at the top and being done with it. That's not actually safe - you're just telling the compiler to shut up about it.

I don't see this problem going away just by making @unsafe the default. With this arguments one can think that people will not use @safe at all and that's it.

-- 
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
Y2K
- what a disappointment... i had at least expected one nuclear plant to blow
November 06, 2009
On Thu, 05 Nov 2009 19:44:55 -0500, Walter Bright <newshound1@digitalmars.com> wrote:

> Steven Schveighoffer wrote:
>> That is, I have a mutable reference x, I want to make it immutable.  How do you write a function to do that?
>>  i.e.:
>>  @safe void foo()
>> {
>>    x = new X();
>>    x.modifyState(5);
>>    immutable(X) ix = ???; // how to write this part
>> }
>
> If you, the writer of foo(), know that there are no other mutable references to x you can cast it to immutable - but you'll have to mark the function as @trusted.

But what if I don't what the whole function to be trusted, just that creation section?  I have to create a new function just to create the data?

Maybe function-level granularity isn't good enough...

-Steve
November 06, 2009
Steven Schveighoffer wrote:
> But what if I don't what the whole function to be trusted, just that creation section?  I have to create a new function just to create the data?

Separate out the trusted code to a separate function.

> Maybe function-level granularity isn't good enough...
November 06, 2009
On Thu, 05 Nov 2009 21:17:08 -0500, Walter Bright <newshound1@digitalmars.com> wrote:

> Steven Schveighoffer wrote:
>> But what if I don't what the whole function to be trusted, just that creation section?  I have to create a new function just to create the data?
>
> Separate out the trusted code to a separate function.

Although that's a solution, it seems artificial to have to build a separate function just to allocate some immutable object.  If unsafe code is truly going to be a rare occurrence, you might want to allow as fine grained control as possible over where the compiler ignores safety.  Having to create artificial boundaries that cause performance problems/code bloat doesn't seem right to me.

However, I'll let it go, I don't know the ramifications since allocating immutable objects is a rare occurrence, and I'm not sure how it will be done.  I am also not sure how solid a use case this is (allocating an object, then manipulating it via methods before changing it to immutable).

-Steve
November 06, 2009
Michel Fortin, el  5 de noviembre a las 19:43 me escribiste:
> On 2009-11-05 19:14:47 -0500, Walter Bright <newshound1@digitalmars.com> said:
> 
> >Andrei Alexandrescu wrote:
> >>Are we in agreement that @safe functions have bounds checking on regardless of -release?
> >
> >You're right from a theoretical perspective, but not from a practical one. People ought to be able to flip on 'safe' without large performance penalties.
> >
> >If it came with inescapable large performance penalties, then it'll get a bad rap and people will be reluctant to use it, defeating its purpose.
> 
> But if you remove bound checking, it isn't safe anymore, is it?

100% safe doesn't exist. If you think you have it because of bound-checking, you are wrong.

> Sometime safety is more important than performance. If I needed performance in a safe program, I'd profile and find the bottlenecks, review carefully those parts of the code slowing down the program, then when I trust them perfectly I'd add the @trusted attribute. @trusted should remove bound checks (in release mode). @safe should keep them to keep other less trustworthy pieces of of the program truly safe.

What if I'm using an external library that I don't control? *That's* the problem for me, I want to be able to compile things I *trust* as if they were *trusted* :)

> That said, I'd be in favor of a compiler switch to enable/disable runtime checks in release mode... perhaps "-safe" could return as way to generate truly safe binaries even in release mode. This would also make it pretty easy to evaluate how much impact those runtime checks have on final executable (by turning on and off the compiler switch).

I vote for an -unsafe (and/or -disable-bound-check). Safe should be the
default.

-- 
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
Lo último que hay que pensar es que se desalinea la memoria
Hay que priorizar como causa la idiotez propia
Ya lo tengo asumido
	-- Pablete, filósofo contemporáneo desconocido