www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Assuring resource usage protocols

reply Manfred Nowak <svv1999 hotmail.com> writes:
A decade ago I detected that in layered software products the
layer higher in the hierarchy implements a protocol on the
resource usage of the lower layer. 

In terms of encapsulation I emphasized this as a principal design
flaw. 

The discussion on the "destructor bug" reminded me of those
thaughts: 
http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/4636

From this discussion one can conclude also, that the behaviour of
destructors in D is not in accordance with the developers thinking
of them: 

| bypass the normal destructor restrictions, which shouldn't be
| there in the first place.
(AJG in the thread mentioned above)

Therefore I see a danger, that D will be considered as a broken 
language in terms of developers relying on the "normal" behaviour 
of destructors.

In type theory protocols on resource usage seem to get awareness:
"An Effective Theory of Type Refinements"
http://www-2.cs.cmu.edu/~rwh/papers/effref/icfp03.pdf 

My idea a decade ago was to interpret the functional elements of an 
implementation as an alphabet and the protocol as a language over 
this alphabet. Thus a resource usage assurance can be interpreted 
as an LALR(1)-parser controlling the accesses to the resource.

Furthermore a parser can be used to automatically repair violations 
of the protocol by means of an error recovery.

At that time I experimented with an LALR-parser driven by the 
elements of the alphabet, i.e. functions and procedures, and the 
grammar, i.e. protocol. The result was, that the idea wasnt wrong 
in general but would not succeed because the developer community 
was used to this habit of developing.

The same argument now holds with D to implement it.

-manfred
Aug 01 2005
parent reply pragma <pragma_member pathlink.com> writes:
In article <dcn4en$194a$1 digitaldaemon.com>, Manfred Nowak says...
A decade ago I detected that in layered software products the
layer higher in the hierarchy implements a protocol on the
resource usage of the lower layer. 

In terms of encapsulation I emphasized this as a principal design
flaw. 

 <snip>

Therefore I see a danger, that D will be considered as a broken 
language in terms of developers relying on the "normal" behaviour 
of destructors.
I'm almost certainly missing the boat here (with respect to language, grammar and protocol layering), so please forgive my ignorance as I dive into the topic. Will the below help, or compound the problem of abnormal destructor behavior? While I cannot speak to how D's grammar may apply to this issue, I do feel that D's constructor behavior is indeed a flaw with D's implementation, not its design. The bigger question is: can we get a behavior change out of the D language that will satisfy a more "normal" design? All I can think of is the impact on the GC, and how it may be more costly at runtime than its worth. Anyway, the example you cited could be helped with a shim, say something like "GC.isValid(Object ptr)" or "GC.exists(void* ptr)" that would check to make sure that a reference is still valid. It may not be pretty, but its well beyond what C and C++ gives us for the same problem (AFAIK, nothing).
 class Foo{
   Bar myref;
   Foo(){ myref = new Foo(); }
   ~Foobar(){ if(GC.isValid(myref)) myref.cleanup(); } 
 }
'isValid' would simply check an Object's destructor or typeinfo address to ensure that its still within reachable memory. Also, the issue with destructors can manifest itself in another, much more infurating, way. If you create an object inside a Dll, using the shared-GC technique, the GC blindly assumes that the object's destructor will be reachable at program termination. If you then unload that Dll before program termination, your good programming pracitce is rewarded with a GPF/segfault all becuase you (unknowingly) assasinated that object's destrctor before it was collected. Like above the GC could just simply check for a pointer's validity - EricAnderton at yahoo
Aug 02 2005
parent AJG <AJG_member pathlink.com> writes:
Hi,

I'm almost certainly missing the boat here (with respect to language, grammar
and protocol layering), so please forgive my ignorance as I dive into the topic.
Will the below help, or compound the problem of abnormal destructor behavior?
It doesn't really solve the problem I originally stated (parents that need to cleanup after children that don't cleanup after themselves). I don't think it will compound the problem either. It would be more of an improvement to the GC (a kind of fine tuning), since it would provide more information.
While I cannot speak to how D's grammar may apply to this issue, I do feel that
D's constructor behavior is indeed a flaw with D's implementation, not its
design.
I assume you mean destructors here? If so, I agree it's a problem with the implementation (more specifically, of the GC implementation).
The bigger question is: can we get a behavior change out of the D
language that will satisfy a more "normal" design?  All I can think of is the
impact on the GC, and how it may be more costly at runtime than its worth.
Anyway, the example you cited could be helped with a shim, say something like
"GC.isValid(Object ptr)" or "GC.exists(void* ptr)" that would check to make sure
that a reference is still valid.  It may not be pretty, but its well beyond what
C and C++ gives us for the same problem (AFAIK, nothing).
IIRC this is not true. C++ let's you access (as it should) children in the destructor. C doesn't have OO so I think the point is moot.
 class Foo{
   Bar myref;
   Foo(){ myref = new Foo(); }
   ~Foobar(){ if(GC.isValid(myref)) myref.cleanup(); } 
 }
'isValid' would simply check an Object's destructor or typeinfo address to ensure that its still within reachable memory.
This would be useful to prevent a segmentation fault if the child is indeed gone (collected by the GC). But if it's gone, then that child is un-cleanable and you're left with an open database, uncommitted changes, locked hardware, unreleased mutex, or what have you.
Also, the issue with destructors can manifest itself in another, much more
infurating, way.

If you create an object inside a Dll, using the shared-GC technique, the GC
blindly assumes that the object's destructor will be reachable at program
termination.  If you then unload that Dll before program termination, your good
programming pracitce is rewarded with a GPF/segfault all becuase you
(unknowingly) assasinated that object's destrctor before it was collected.  
Yeah. It'd be nice if the GC could collect everything in a module properly (and call destructors) when it's unloaded dynamically. Cheers, --AJG.
Aug 02 2005