DIP69 - Implement scope for escape proof references

via Digitalmars-d digitalmars-d at puremagic.com
Wed Dec 17 05:34:17 PST 2014


On Wednesday, 17 December 2014 at 05:28:35 UTC, Walter Bright 
wrote:
> On 12/16/2014 5:37 AM, "Ola Fosheim Grøstad" 
> <ola.fosheim.grostad+dlang at gmail.com>" wrote:
>> The current proposal is either too limiting or not limiting 
>> enough.
>
> I'm afraid I don't understand at all what you wrote.

Well, look at it this way: D1 took 1990s style C++ application 
programming model and made it more convenient with a GC. Having a 
GC-memory model with the possibility of stack/heap allocations as 
optimizations can keep the language simple. D2 is more of a 
library author's language, but without GC you need to deal with 
different types of ownership.

If you toss out the GC, and want the same level of safety and 
generality you either:

1. need to track ownership add dynamic runtime checks
2. provide a full blown proof system (not realistic)
3. provide means for the programmer to "help" the semantic 
analysis

What you want is a combination of 1 and 3, but you don't need to 
keep them separate. Since refcounting is expensive, you don't 
want that everywhere. For stack allocated objects you have an 
implicit "refcounting" in the nesting of scopes, you only need to 
track scope-depth.

If the compiler knows that a returned object is stack allocated, 
then it can check that by comparing against the stack frame 
address since the stack grows downwards in an ordered fashion. 
And in most cases it should be able to elide the check.

If you also maintain information about order (stack depth) among 
the stack allocated objects a function receives through reference 
parameters (for every function call), then you can safely combine 
the stack allocated objects you receive through parameters in 
aggregates, like inserting an stack allocated element into a 
container.

Since D is increasingly becoming a library author's language, you 
probably also would benefit more from strengthening the template 
support by having a templated ref-type rather than "scope ref". 
You could define protocols (e.g. predefined UDAs) that tells the 
compiler what kind of key properties the library type provides, 
such as ownership. Then use that for a more generic approach to 
optimization and escape analysis and let the 
ownership-reference-types be library types. If semantic analysis 
gets rid of the dynamic aspects of a referencs (such as reference 
counting) then the compiler should be able to use the same 
function body, and in other cases just add a inferred wrapper to 
a generic function body. So the code bloat can be limited.

If all references to external resources (like the heap) in the 
stack allocated object is owned by the object, then you can treat 
those as a whole. But you need the compiler to understand what 
ownership is if it is to guarantee memory safety in the kind of 
situations where memory safety is known to be difficult to 
achieve.

The alternative is to state that @safe is not covering non-GC 
memory and that one should stick to vetted library code when 
writing @safe code that does not use the GC. I actually find that 
acceptable for D2. In D2 you would be better off spending the 
effort at finding ways to turn automatically turn GC allocations 
into stack allocations as optimizations. Then you can find a more 
general and powerful ownership-oriented approach for non-GC 
applications for a new major version of D.

It is not realistic that people will annotate with "scope ref", 
and compiler inference could make updates to libraries break 
application code if you get false negatives. Function signatures 
are contracts, they ought to be explicit for libraries. So having 
library functions act as "scope ref" without it being explicit in 
the signature is not necessarily a good idea.


More information about the Digitalmars-d mailing list