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