November 05, 2009
Following the safe D discussions, I've had a bit of a change of mind. Time for a new strawman.

Based on Andrei's and Cardelli's ideas, I propose that Safe D be defined as the subset of D that guarantees no undefined behavior. Implementation defined behavior (such as varying pointer sizes) is still allowed.

Memory safety is a subset of this. Undefined behavior nicely covers things like casting away const and shared.

Safety has a lot in common with function purity, which is set by an attribute and verified by the compiler. Purity is a subset of safety.

Safety seems more and more to be a characteristic of a function, rather than a module or command line switch. To that end, I propose two new attributes:

@safe
@trusted

A function marked as @safe cannot use any construct that could result in undefined behavior. An @safe function can only call other @safe functions or @trusted functions.

A function marked as @trusted is assumed to be safe by the compiler, but is not checked. It can call any function.

Functions not marked as @safe or @trusted can call any function.

To mark an entire module as safe, add the line:

   @safe:

after the module statement. Ditto for marking the whole module as @trusted. An entire application can be checked for safety by making main() safe:

    @safe int main() { ... }

This proposal eliminates the need for command line switches, and versioning based on safety.
November 05, 2009
== Quote from Walter Bright (newshound1@digitalmars.com)'s article
> Following the safe D discussions, I've had a bit of a change of mind.
> Time for a new strawman.
> Based on Andrei's and Cardelli's ideas, I propose that Safe D be defined
> as the subset of D that guarantees no undefined behavior. Implementation
> defined behavior (such as varying pointer sizes) is still allowed.
> Memory safety is a subset of this. Undefined behavior nicely covers
> things like casting away const and shared.
> Safety has a lot in common with function purity, which is set by an
> attribute and verified by the compiler. Purity is a subset of safety.
> Safety seems more and more to be a characteristic of a function, rather
> than a module or command line switch. To that end, I propose two new
> attributes:
> @safe
> @trusted
> A function marked as @safe cannot use any construct that could result in
> undefined behavior. An @safe function can only call other @safe
> functions or @trusted functions.
> A function marked as @trusted is assumed to be safe by the compiler, but
> is not checked. It can call any function.
> Functions not marked as @safe or @trusted can call any function.
> To mark an entire module as safe, add the line:
>     @safe:
> after the module statement. Ditto for marking the whole module as
> @trusted. An entire application can be checked for safety by making
> main() safe:
>      @safe int main() { ... }
> This proposal eliminates the need for command line switches, and
> versioning based on safety.

Vote++.  The thing I like about it is that, if you've got a well-debugged function that does some well-encapsulated unsafe things (performance hacks, etc.) and needs to be called by safe functions, safety doesn't become viral and force you to reexamine the implementation of your well-encapsulated unsafe function.  On the other hand if you've got a function that does non-encapsulated unsafe things that the caller has to understand in order to use it properly (e.g. something like GC.setAttr, which can make regions of memory unscanned by the GC), this should *not* be callable from safe code no matter what.

As long as I know that safety isn't going to be viral and force me to modify code that's got tons of performance hacks internally but has a safe interface (and as long as getopt gets fixed), I'm actually starting to like SafeD.
November 05, 2009
== Quote from Walter Bright (newshound1@digitalmars.com)'s article
> Following the safe D discussions, I've had a bit of a change of mind.
> Time for a new strawman.
> Based on Andrei's and Cardelli's ideas, I propose that Safe D be defined
> as the subset of D that guarantees no undefined behavior. Implementation
> defined behavior (such as varying pointer sizes) is still allowed.
> Memory safety is a subset of this. Undefined behavior nicely covers
> things like casting away const and shared.
> Safety has a lot in common with function purity, which is set by an
> attribute and verified by the compiler. Purity is a subset of safety.
> Safety seems more and more to be a characteristic of a function, rather
> than a module or command line switch. To that end, I propose two new
> attributes:
> @safe
> @trusted
> A function marked as @safe cannot use any construct that could result in
> undefined behavior. An @safe function can only call other @safe
> functions or @trusted functions.
> A function marked as @trusted is assumed to be safe by the compiler, but
> is not checked. It can call any function.
> Functions not marked as @safe or @trusted can call any function.
> To mark an entire module as safe, add the line:
>     @safe:
> after the module statement. Ditto for marking the whole module as
> @trusted. An entire application can be checked for safety by making
> main() safe:
>      @safe int main() { ... }
> This proposal eliminates the need for command line switches, and
> versioning based on safety.

Oh yeah, and now that it looks like D is getting annotations, can/should we make pure and nothrow annotations, i.e. @pure, @nothrow, for consistency?
November 05, 2009
On Thu, 05 Nov 2009 13:33:09 -0500, Walter Bright <newshound1@digitalmars.com> wrote:

> Following the safe D discussions, I've had a bit of a change of mind. Time for a new strawman.
>
> Based on Andrei's and Cardelli's ideas, I propose that Safe D be defined as the subset of D that guarantees no undefined behavior. Implementation defined behavior (such as varying pointer sizes) is still allowed.
>
> Memory safety is a subset of this. Undefined behavior nicely covers things like casting away const and shared.
>
> Safety has a lot in common with function purity, which is set by an attribute and verified by the compiler. Purity is a subset of safety.
>
> Safety seems more and more to be a characteristic of a function, rather than a module or command line switch. To that end, I propose two new attributes:
>
> @safe
> @trusted
>
> A function marked as @safe cannot use any construct that could result in undefined behavior. An @safe function can only call other @safe functions or @trusted functions.
>
> A function marked as @trusted is assumed to be safe by the compiler, but is not checked. It can call any function.
>
> Functions not marked as @safe or @trusted can call any function.
>
> To mark an entire module as safe, add the line:
>
>     @safe:
>
> after the module statement. Ditto for marking the whole module as @trusted. An entire application can be checked for safety by making main() safe:
>
>      @safe int main() { ... }
>
> This proposal eliminates the need for command line switches, and versioning based on safety.

I like how the attribute can be applied at different levels.  Sounds good to me.  Should you also be able to mark a whole struct/class as @safe/@trusted, since it's generally a container for member functions?

Care to define some rules for "undefined behavior?"

-Steve
November 05, 2009
Walter Bright:

> Following the safe D discussions,

I was busy, I am sorry, I have not followed it, but I have read part of the PDF of Cardelli shown by Andrei.


> Based on Andrei's and Cardelli's ideas, I propose that Safe D be defined as the subset of D that guarantees no undefined behavior.

I am asking for this for a lot of time, because SafeD meant MemorySafeD so far.
So D is again converging toward something similar to what C# has chosen long time ago. Maybe it's time to look better at C#.


> Safety seems more and more to be a characteristic of a function, rather than a module or command line switch.

In C# you use something like:

unsafe {
  // lot of code
}

I think that's a good solution. Things are meant as safe unless marked as unsafe. You can mark a whole block of code as unsafe putting it into those brackets. D may do the same. Also single functions may have the @unsafe attribute.


> To mark an entire module as safe, add the line:
> 
>     @safe:
> 
> after the module statement. Ditto for marking the whole module as @trusted.

Why is this not good?
module foo(unsafe);
(But the unsafe {...} may be enough for a whole module too).


> An entire application can be checked for safety by making main() safe:
> 
>      @safe int main() { ... }
> 
> This proposal eliminates the need for command line switches, and versioning based on safety.

I may have missed some important parts of the discussion, but this test seems fit for a command line switch (C#uses one for this purpose. If your program has one or more unsafe parts, it needs an unsafe comment line switch. I agree it's a tool a little blunt).

Bye,
bearophile
November 05, 2009
On 2009-11-05 13:33:09 -0500, Walter Bright <newshound1@digitalmars.com> said:

> Safety seems more and more to be a characteristic of a function, rather than a module or command line switch. To that end, I propose two new attributes:
> 
> @safe
> @trusted

Looks like a good proposal.

That said, since most functions are probably going to be safe, wouldn't it be better to remove @safe and replace it by its counterpart: an @unsafe attribute? This would make things safe by default, which is undoubtedly safer, and avoid the unnecessary clutter of @safe annotations everywhere.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

November 05, 2009
On Thu, 05 Nov 2009 14:57:48 -0500, Michel Fortin <michel.fortin@michelf.com> wrote:

> On 2009-11-05 13:33:09 -0500, Walter Bright <newshound1@digitalmars.com> said:
>
>> Safety seems more and more to be a characteristic of a function, rather than a module or command line switch. To that end, I propose two new attributes:
>>  @safe
>> @trusted
>
> Looks like a good proposal.
>
> That said, since most functions are probably going to be safe, wouldn't it be better to remove @safe and replace it by its counterpart: an @unsafe attribute? This would make things safe by default, which is undoubtedly safer, and avoid the unnecessary clutter of @safe annotations everywhere.

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.

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".

-Steve
November 05, 2009
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.
November 05, 2009
Steven Schveighoffer wrote:
> Care to define some rules for "undefined behavior?"

My list may be of help.

Andrei
November 05, 2009
Steven Schveighoffer wrote:
> On Thu, 05 Nov 2009 14:57:48 -0500, Michel Fortin <michel.fortin@michelf.com> wrote:
> 
>> On 2009-11-05 13:33:09 -0500, Walter Bright <newshound1@digitalmars.com> said:
>>
>>> Safety seems more and more to be a characteristic of a function, rather than a module or command line switch. To that end, I propose two new attributes:
>>>  @safe
>>> @trusted
>>
>> Looks like a good proposal.
>>
>> That said, since most functions are probably going to be safe, wouldn't it be better to remove @safe and replace it by its counterpart: an @unsafe attribute? This would make things safe by default, which is undoubtedly safer, and avoid the unnecessary clutter of @safe annotations everywhere.
> 
> 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.

While I agree with your point, quick question: could you use ref parameters instead? Ref will be usable in SafeD.

Andrei
« First   ‹ Prev
1 2 3 4 5 6 7 8 9 10
Top | Discussion index | About this forum | D home