More keywords? Or fewer?

Davidson Corry davidsoncorry at comcast.net
Wed Apr 30 21:51:57 PDT 2008


I have been following, fascinated, the discussions of keywords such as 
pure, const, invariant and Janice Caron's elegantly evocative 
"paintable". It occurred to me the other day to wonder if all this is 
heading in the wrong direction.

Memory management is difficult and fragile. Many keywords, language 
constructs and library routines were introduced to support it, such as 
malloc/free, new/delete, dispose, Set obj = Nothing etc. But it remained 
difficult and fragile... until garbage collection was built into 
languages, and we just forgot about it. Now nine times out of ten we 
don't use memory management keywords at all [1], and when we do, nine 
times out of ten we shouldn't have.

Are keywords for availability -- const, invariant, synchronized, etc. -- 
awaiting the same sort of epiphany?

 --------------

An object must be responsible for setting and for reporting its own 
state. No outside client can be allowed to change the object's member 
data, nor to set the algorithms by which those data are calculated and 
reported. However, the object can provide accessor methods through which 
a client can request the /object/ do to so itself -- set, get, etc. [2]

At various times, an object might be in one of three conditions of 
availability: [3]
 - changeable (clients can call methods which will modify the object's 
state)
 - inspectable (clients can call methods which report the object's state 
but do not change it)
 - detectable (clients can determine that the object exists, but not 
inspect its state nor change it)
For instance, while executing a state-modifier method, the object's 
consistency guarantees - its class invariant - is temporarily suspended. 
So the object cannot allow potential clients on other threads even to 
inspect it, much less to change it. But it should allow other threads to 
detect its existence so that they can decide whether or not to wait for 
it to get its act together.

An object's availability may change from time to time during the 
execution of the program. An object may choose to be changeable at some 
point, and then later "lock itself down" so that it is inspectable but 
denies all clients access to its state-modifier methods. And then, 
perhaps, open itself up again. Availability might be considered to be a 
distinct property of all objects, inherited from the uber-parent Object 
class. An object may explicitly set its availability property, /or the 
language might set it automatically at runtime/, or both.

Declaring an object const is the limiting case that the object is only 
inspectable -- that is, makes no modifier-methods available -- 
throughout the lifetime of of the object (or the program). No client can 
ask the object to change itself, although the object may itself choose 
to change. Declaring an object invariant is the same, except that the 
object also promises not to change itself. A compiler may be able to 
take advantage of optimization opportunities for objects that are 
lifetime const or invariant. Similarly, there may be opportunities for 
runtime optimizations on objects that change their availability dynamically.

A language-system could inspect the source code, "drilling down" into 
sub-objects, and infer which objects and methods are effectively const 
or invariant, and (if compiled for multi-threaded or multi-programmed 
access) which need locking and rendezvous support. Explicit keywords are 
not required. However, to do so requires that the language-system have 
access to the source code for the entire system, and is thus in conflict 
with separate compilation, and with coding for libraries. [4] [5]

 --------------------

And now for the Democratic response:

How a program actually behaves at runtime implies a contract for its 
objects. Yet languages which implement design-by-contract allow 
programmers to explicitly /declare/ a contract separate from the implied 
one. And this is an advantage because the implied contract cannot be 
readily perceived by reading the code, and because conflicts between the 
implied and declared contracts can be caught at compile time (e.g. 
Spec#) and at runtime.This simplifies debugging and enhances program 
correctness. So keywords for contracting are justified.

Could keywords (or object properties or library routines automatically 
provided by the language) for constness, purity, synchronization also be 
a double-check on the implied mutability and thread-singularity of 
runnable code? Hmm...

 --------------------

 -- Davidson Corry


[1] C++ new did both memory management and object creation. In Java/C#/D 
it is strictly a creation keyword.
[2] if the language-system chooses to /implement/ an accessor as a 
direct access, fine. Conceptually it's still a method managed by the object.
[3] roughly, mutable, const and locked. But I am trying to avoid using 
actual keywords with specific technical meanings
[4] Or is it? The compiler could embed in the object file, or in the 
library export definition, metadata that declares the relevant 
properties of the public objects, and allows the linker to correctly 
optimize and support whole-system linkage. This pushes what is 
traditionally considered part of the compiler's job into the linker, but 
so what?
[5] It's also in conflict with Walter's stated goal of making D small 
and clean enough for others to implement compilers for it. Oh well, 
there's always the "supported syntactically but not semantically" 
option. ;-)



More information about the Digitalmars-d mailing list