Newbie initial comments on D language - scope

Edward Diener eddielee_no_spam_here at tropicsoft.com
Sat Feb 2 17:57:37 PST 2008


Walter Bright wrote:
> Edward Diener wrote:
>> In your above, if the c object is 'scope', whether it is because the C 
>> class is 'scope' or, as in your example, you specify 'scope' on the 
>> object ( which in current D is the same thing as saying that the C 
>> class is 'scope' ) then the assignment to another object makes that 
>> object 'scope' automatically. This is yet another reason why 'scope' 
>> at the compiler should be tracked at the object level, not at the 
>> class level. The canonical situation is:
>>
>> class C { ... }
>> scope class D : C { ... }
>>
>> scope ( redundant IMO ) D  d = new D(...);
>> C c = d;
>>
>> Clearly c, whose polymorphical type is a D, has to be 'scope'.
> 
> Let's look at it by analogy to 'const'. Implicitly converting a const D 
> to its base class will produce a const C, not a C. A const C cannot be 
> assigned to a C.
> 
> I think it should work similarly with scope, and that like const, it 
> should be part of the type system (a proxy struct would accomplish 
> that). Making it a dynamic part of the object would exact a heavy cost 
> for most objects which don't need it.

Your analogy to C++'s 'const' is a bad one.

The C++ 'const' refers to a quality of the object while the D 'scope' 
refers to a quality of the type. There is no equivalent of 'const' in 
C++ which refers to the type. Once we say that a type is 'scope' in D we 
should no longer have to say that an object of that type is 'scope'. An 
object of that type should be 'scope' automatically and the user of that 
object should not care or even need to know. In C++ the user of an 
object specifically says it is 'const' to set the quality of the object 
to something ( one can not change the object ). Your analogy is mixing 
apples and oranges. These are different things.

What I am saying is that an object whose type is 'scope' is treated 
magically by the compiler in that the compiler is now doing reference 
counting on it and calling its destructor when the last reference goes 
out of scope. Furthermore as that object gets reference assigned the 
reference count is manipulated and whatever object is specified in that 
reference assignment, as long as it is allowable by the compiler by the 
rules of D, takes part in the 'scope' magic. In a polymorphic language 
this means that you should associate 'scope' with the dynamic type of 
the object, not its static type, and how you decide to do that is up to 
you. Think of it as wrapping a boost::shared_ptr around the object and 
for every object to which you legally assign/copy it a boost::shared_ptr 
gets wrapped around that object.

I agree this adds some overhead, but so what. Using boost::shared_ptr 
also imposes overhead and whole generation of programmers have somehow 
survived the extra x bytes per object in an age where physical memmory 
is in the gigabytes and virtual memory in 64 bit systems in the quadrabytes.

My added suggestion is that when applying the 'scope' keyword to the 
object, and not the type, this essentially means that the compiler now 
treats that object as 'scope' even though the type is not 'scope'. I 
will call this object 'scope' injection. My suggestion for this is based 
solely on the practical consequences:

1) Allow the instantiator of a type to have 'scope' control over the 
object even when the designer of the type does not specify it as a 
'scope' type. The user may know something about using the type at 
run-time that the class designer can not know, makes optional, or even 
disregards.

2) Following from the above, the most obvious practical cases occur when 
the type is created from a template class/struct, when the type is some 
built-in language container which can hold polymorphic objects of some 
base class type, and when the type embeds an object of 'scope' class 
type which may only be used in a corner case so that the designer of the 
type leaves scoping up to the user.

In other words the flexibility of control would be wonderful and, I 
believe, often necessary. Having both the class designer be able to 
'scope' the type and the end user be able to 'scope' an object of any 
type ( which has a destructor ) is the ultimate ideal. If you wanted to 
go even further you could allow the end-user to 'unscope' an object of a 
'scope' type when instantiating the object, even though the benefits of 
doing this seem to be practically negligible.

I view your choices as, from most desirable to least desirable:

1) Keep tracks of the objects themselves at run-time to see if they are 
'scope' or not. This allows object 'scope' injection and refernce 
assignment to objects whose static type is not 'scope' to make them 'scope'.

2) Keep track of the dynamic type of the objects themselves in order to 
see whether the dynamic type of the object is 'scope'. This does not 
allow object 'scope' injection, but does allow reference assignment to 
objects whose static type is not 'scope' since you are only considering 
the dynamic type of the object and not the static type to determine if 
the object should be 'scope'.

3) Keep track of only the static type of the object. This does not allow 
object 'scope' injection nor even reference assignment to objects whose 
static type is not 'scope'.

I view choice 3 as pretty poor and would really like to see choice 1 
rather than choice 2 for practical reasons.

I hope this at least gives you food for further thought.



More information about the Digitalmars-d mailing list