Generic creation
This technical note describes the mechanism for creating objects of
formal generic types, as present in ISE Eiffel release 4.3. With the
exception of an added Overview (section 1 below), it is identical to the
text of a language extension proposal submitted by ISE to the Nonprofit
International Consortium for Eiffel (NICE).
Note that the examples use the new syntax for creation instructions
which is intended to replace the classical create x.
Both forms will continue to be supported for several years.
All page numbers refer to the current definition of Eiffel: the book Eiffel:
The Language.
1. Overview
The problem addressed by this extension is simple: how to create an
object of a type known only through a formal generic parameters. In a
class C [G], you may have
declared x of type G, and want to
execute a creation instruction
for some creation procedure make
of your choice.
For this to be type-safe, however, we need to know a little more
about G, since in the most general
case it represents an arbitrary type, so we have no clue about what kind
of creation procedure it may require if any, and with what arguments.
For this reason such creation instructions have been prohibited in
Eiffel until now. You had to encapsulate the creation in a procedure on
the client side (where the actual generic parameter is known --
separately for each client).
The new mechanism removes this limitation, due to the following
elegant idea (credit for which is entirely due to Mark Howard from Axa
Rosenberg, formerly Rosenberg Institutional Equity Management). It is
based on the Eiffel technique of constrained genericity. To guarantee
that the above creation instruction is valid, just make sure that G
is a constrained generic parameter, with a class declaration of the form
class C [G ->
CONSTRAINT create make, ...] ...
listing make as one of the
applicable creation procedures. The rules are that
make must be a procedure of the
constraining type, CONSTRAINT,
with of course the right argument types.
When you use a generic derivation C [T],
where type T must conform to CONSTRAINT,
the version of make in T
(possibly renamed, redefined etc.) must be listed as a creation
procedure for T.
This ensures type safety.
The beauty of the scheme is that make,
or any of the other creation procedures used for entities of type G,
does not need to be a creation procedure in CONSTRAINT;
it simply needs to be a procedure with the appropriate arguments. Only
for descendants of CONSTRAINT used
as actual generic parameters does it matter that make
be a creation procedure.
This allows in particular CONSTRAINT
to be a deferred class.
This overview should be sufficient to any Eiffel user desiring to use
the mechanism. The detailed specification follows.
2. Syntax
The production for Constraint, on page 201,
which reads
Constraint == "->" Class_type
becomes
Constraint == "->" Class_type [Creation_constraint]
with (see page 285)
Note: in the syntax for Creators, page 285,
the keyword creation will be
replaced by create for simplicity.
(The older keyword will continue to be accepted by compilers.)
3. Validity
New validity rule VTCC, page 201:
A Constraint is valid if and only if
every identifier listed in the Feature_list
of its Generic_creators, if any, is the
name of a procedure of the base class of its Creator_type.
Adaptation of VTCG, page 203 (with clause 3 already adapted for the
"Generics in Constraints" change) now reads:
Let C be a constrained generic
class. A Class_type CT
having C as base class is valid if
and only if CT satisfies the
Unconstrained Genericity rule (VTUG, page 201) and in addition, for
any Formal_generic parameter G
in the declaration of C having a
constraint, then if D is the Class_type
listed in the constraint and T,
with base class BT, is the Type
corresponding to G in the Actual_generics
list of CT:
3. T conforms to the type obtained from D
by substituting any occurrence of a formal generic parameter of C
by the corresponding actual parameter.
4. If the constraint for G has a
Generic_creators part, then the C
version of every procedure of BT
listed (as per rule VTCC, page 201) in that part is declared in BT
as a creation procedure.
In VGCC, page 286, replace clause 1 by
If T is a Formal_generic_name
(that is to say, a formal parameter of the class where the instruction
appears), then the corresponding formal generic parameter has a Constraint
part with a Generic_creators part, and
the creation instruction has a Creators part whose feature is one of
the procedures listed (as per rule VTCC, page 201) listed in the Generic_creators
part. Cases 2 to 6 assume that T
is not a Formal_generic_name.
4. Semantics
The semantics of a creation call of the form
create x.proc (arguments)
where the type of x is (as per VGCC
(1)) a formal generic parameter with a constraint listing proc
in its Generic_creators part, is to create
an object of the type T used as the
corresponding actual generic þarameter in the generic derivation
considered, using as creation procedure the version of proc
in the base class BT of T.
As per VGCC (3), BT must declare
that version as a creation procedure. |