Newbie initial comments on D language - scope

Edward Diener eddielee_no_spam_here at tropicsoft.com
Wed Jan 30 18:46:24 PST 2008


Walter Bright wrote:
> Edward Diener wrote:
>> Walter Bright wrote:
>>> I'm working on adding destructors to structs, which I'm thinking 
>>> should completely supplant scoped classes. RAII is a much more 
>>> natural fit with structs than it ever will be for classes.
>>
>> Please reconsider that decision, especially in the light of the 
>> restrictions to structs in D which classes do not have. You would 
>> essentially be saying that any class designer, who would want to 
>> incorporate deterministic destruction in his class because of a need 
>> to free a resource upon class destruction, is constrained in D to 
>> using a struct rather than a class.
>>
>> In that case why bother, since structs are so much less than a class 
>> in features. You might just as well say "I did not want the challenge 
>> of RAII in D, a GC language, so I will just kill it this way." If you 
>> really don't want RAII in D, which simply and fairly enough means you 
>> want the release of resources in your GC environment to always be done 
>> manually, just don't implement it at all. That is much more 
>> straightforward than attempting to support but doing it in such a way 
>> that makes it impossible for a class designer to implement it.
>>
>> The current 'scope' keyword for RAII is very limited. My OP was not 
>> questioning that but objecting to the redundant way it had to be used 
>> even in that environment. However, making it more limiting rather than 
>> less limiting just kills it entirely IMO, where you should be seeking 
>> to go in exactly the opposite direction.
> 
> Maybe you're selling structs short :-). With RAII structs, to make an 
> RAII class, one could create a wrapper struct template:
> 
> struct Wrapper(C)
> {
>     C c;
>     ~this()
>     {
>         delete c;
>     }
> }
> 
> This is oversimplified, as there would also need to be a mechanism to 
> forward operations from the struct to the class C, copy constructors, 
> etc., but I think it is conceptually sound.
> 
> Such wrapper structs could, for example, be written to reference count 
> their argument equivalently to the C++ shared_ptr<>.

OK, I see where you are going.

> 
>  From another point of view, an RAII type is fundamentally a value type, 
> whereas classes are fundamentally reference types. By using the wrapper 
> approach to impart some value (i.e. RAII) semantics to a reference type, 
> the operations on that reference type can be carefully controlled by the 
> wrapper designer to prevent such problems as references escaping the 
> scope - solutions which are problematic to put in the core language.
> 
> I'm not sure what you mean by saying that structs are so much less than 
> classes. Structs aren't a subset of classes, they are a fundamentally 
> different animal - a value type, as opposed to a class, which is a 
> reference type. C++ does not distinguish between the two, leaving 
> serious problems such as the "slicing problem", the virtual destructor 
> problem, and trying to prevent users of your C++ class from using it as 
> a value when it should be a reference or vice versa.
> 
> Behaviors which are a natural fit for reference types include 
> inheritance, polymorphism, and gc (including ref counted gc).
> 
> Behaviors which are a natural fit for value types are scoped allocation, 
> RAII, non-virtual functions.

You have sold me.

When you said 'struct' I was not thinking in terms of a template class, 
ala boost::shared_ptr<T>, but instead of the limitations of 'struct' in 
D as opposed to a class, which tells me that in D a struct is a C++ POD. 
I have not read about templates yet in D so a struct that is a template 
class and wraps an object which is the actual type was beyond my 
thinking. Your idea is absolutely right and I was wrong to criticize it 
without understanding what you meant.

Now that I see where you are going, and you mentioned forwarding in your 
description above, I though of how boost::shared_ptr does it and I 
realized that the C++ 'operator ->' is the key. So I immediately looked 
for the equivalent in D, which would allow this to happen also, which 
would be an op function for the 'operator .'. But I could not find this 
operator supported in the D 1.0 docs. My suggestion then, if you are 
going to make the idea above work, is that you need to support an op 
function for the 'operator .' and then forwarding into the wrapped 
object would be simple and automatic no matter what functionality the 
wrapped object had.



More information about the Digitalmars-d mailing list