Table of Contents
A variable is a storage location with an associated type (its compile-time type). Its value is changed by an assignment or by a prefix or postfix increment or decrement. The Java programming language defines seven kinds of variables; class variables (corresponding to static fields), instance variables (corresponding to non-static fields), array components, method parameters, constructor parameters, exception-handler parameters, and local variables. The last four kinds can be subsumed under the common term local variables for the purpose of this specification.
The XL programming language adopts these kinds of variables and introduces two new kinds of variables:
Query variables (Section 17.1, “Query Variables”) are a new special kind of local variables. Query variables are declared within queries (Chapter 17, Queries) and set by the process of pattern matching (they are bound to values). Their values cannot be set by the programme itself.
Property variables (Section 7.1, “Property Variables”) are declared by the current compile-time model (Section 3.1, “Compile-Time Model”), there is no syntax that declares properties. Property variables can be used similarly to ordinary instance variables, or in quasi-parallel assignments.
Like an instance i
of a class
T
induces
one instance variable for every instance field of
that class T
,
property variables
of i
exist for every
property of T
.
The properties of a (non-array) reference type
T
are declared by the current
compile-time model m
(Section 3.1, “Compile-Time Model”) in the following way:
For every valid identifier n
of the XL programming language for which the method invocation
m.
getDirectProperty(
T, n
)
returns a (non-null) instance
p
of class
de.grogra.xl.lang.Property
, there is a
direct property p
named n
declared in
type T
. The type of this property is
the type returned by the method invocation
p.
getType()
.
For every property p
declared in type T
whose type is a
reference type S
, and for every
non-null reference type
C
that can be assigned to
S
, the method invocation
p.
getTypeCastProperty(
C
)
has to return an instance q
of class
de.grogra.xl.lang.Property
.
q
represents p
's
type-cast property of type C
,
which has to be the same as the type returned by the method invocation
q.
getType()
.
q
is declared in
type T
.
For every property p
declared in type T
whose type is a
non-array reference type S
, and for every
valid identifier n
of the XL programming language for which the method invocation
p.
getSubProperty(
n
)
returns a (non-null) instance s
of class
de.grogra.xl.lang.Property
, there is a
subproperty s
of p
named n
.
s
is declared in type T
.
The type of this property is the type returned by the method invocation
s.
getType()
.
For every property p
declared in type T
whose type is an
array type A[]
,
and if the method invocation
p.
getComponentProperty()
returns a non-null instance r
of class
de.grogra.xl.lang.Property
,
r
represents p
's
component property. Its type is
A
,
which has to be the same as the type returned by the method invocation
r.
getType()
.
r
is declared in
type T
. If the invocation of
p.
getComponentProperty()
returns null, no component property exists.
So far the discussion specifies the compile-time aspects of properties.
For a property p
, an XL compiler uses the
string id
returned by the method invocation
p.
getRuntimeName()
as an identifier for that property in compiled code.
This identifier is used at run-time
in order to determine p
's
run-time property, subsequently denoted by
pR
. Namely, for the
run-time model r
(Section 3.2, “Run-Time Model”) that corresponds to the current
compile-time model for p
, and for the
type loader L
of the immediately enclosing
class, the method invocation
r.
propertyForName(
id
, L
)
has to return
a (non-null) instance pR
of class
de.grogra.xl.runtime.Property
. The type of
pR
is the type of p
.
This run-time
property induces a property variable for every instance of the type
T
in which the original property
p
was declared. The XL programming
language does not specify a format for the idenfifier
id
; it is up to the compile-time and
run-time models to define a suitable scheme.
The XL programming language does not specify how the property variables
of an instance i
are associated internally with that
instance. This depends on the implementation of the
run-time model (Section 3.2, “Run-Time Model”); typically, the values
of property variables are stored in ordinary instance variables.
However, the XL programming language specifies how the values
of property variables
are read and written. Let i
be the instance
and pR
the run-time property to which a property
variable corresponds, S
the
type affix (Section 6.1, “Type Affixes and Type Letters”) of
pR
's
type, and x
the current
extended state of the virtual machine (Chapter 4, Extended State of the Virtual Machine),
then the value of the property variable is the returned value
of the method invocation
pR.
get
S
(
i, x
)
.
A value v
is stored in the
property variable by the method invocation
pR.
set
S
(
i, v, x
)
.
If pR
's compile-time property
p
involves a number
n
of component properties, i.e.,
n
invocations of
getComponentProperty
as described above are necessary
in order to get from a direct property to p
,
then n
indices for array access have to be
on top of x
's int
-stack.
These have to be popped within the implementations of
pR
's
get- and set-methods, where the topmost
value on the stack corresponds to the last component property
in the chain from a direct property to p
.
Compile-time and run-time model implementations
should ensure a reasonable behaviour for properties. E.g., let
p
be a property having an array type
and a component property
q
. For fixed instance i
and valid index k
,
the value of q
's property variable
(assuming that k
has been pushed on the stack)
should be the same as the value of the array component at index
k
of the value of
p
's property variable. However,
the effects of assigning the same value to either the
component property variable or the array component may differ: The
implementation of q
's set-method may involve
a side-effect that, e.g., notifies a set of observers about the
modification of the property. If a value is directly assigned to
the array component, no set-method of a run-time property is involved,
so no notification can be sent.
Property variables are also modified by quasi-parallel assignments.
Contrary to a field, a property is not a member of its declaring type.
Thus, it is not inherited by subclasses or subinterfaces. However,
the semantics of an implementation of the compile-time and run-time model
normally implies that if a property p
named
n
is declared in a typeT
,
then there will be corresponding properties named
n
in subtypes of
T
whose property variables are the same as
those of p
.