Defining global data
There are two aspects here: First, really global data as in Java's static fields or singleton instances, and data that belongs to a given type but cannot be defined within the feature that defines that type because it has to be accessible from the outside as well.
Other languages
static fields
Java, C, etc. provide a modifier static
to declare a field that
exists only once and becomes accessible globally, causing all sorts of problems
since it can be changed from any place, causing all sorts of bugs, in the worst
case races conditions.
once functions
Eiffel provides a modifier once
for features that are executed
only once and return the original result on later calls. They essentially behave
like a single static field in its own class in Java that gets initialized when
it is first read. Race conditions are controlled a little better since access
is read only, but if the result is a reference, we may produce races when
modifying the resulting singleton instance.
Global elements via defines section
We need some mechanism to declare inner features that do not depend on instances
of the feature they are declared in, but which could very well depend on an outer
feature. Examples are the constants zero
and one
in
numeric
or the identity element in monoid
:
# identity element # e T => abstract
It should be possible to use such a global element also via a formal generic
argument, i.e., a constrained generic argument T: monoid
should
allow a call to T.e
to get the identity element. If the actual
generic argument for T is x.y.z
, then T.e
should
execute x.y.z.e
within the outer instance x.y
. An open
question is if any fields of x
and y
should be
accessible by x.y.z.e
since this would require identifying and
storing the desired instance of y
.
Defining outer elements via defines section
One way to achieve this is by using a specific clause defines
(or maybe has
,
static
, outer
) that declares features that end up in
the outer feature but are accessible through <outer>.monoid.e
:
monoid(T monoid.type) defines # identity element # e T => abstract is # associative operation # infix + (other T) T => abstract
Open questions:
- should state of outer features be accessible from features declared in defines clause?
- should fields be allowed to be declared in the defines clause?
- should statements be allowed in defines clause?
- if fields or statements are allowed, when should they be executed?
Global elements
Outer elements are not global, they are local to the outer instance. As long as this instance is not a singleton, these are elements that are local to the outer feature.
Do we need more? What for?