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