This section may be skipped on first reading.
Some notation used in the standard library differs from that found in the traditional languages like C. In particular, fixed-length indexed arrays are called ``vectors.'' The name ``array'' is used for variable-length indexed arrays which allow adding and removing elements from both ends and can expand or shrink at runtime depending on the number of elements they are holding. The indexing operation is denoted by `` !'' (which is an infix version of fetch), because the traditional bracket notation ``[]'' is used by the Cecil language to indicate parameterization of objects and types. For example, printing out an array element (or, more generally, a table element) can be done like this: (a!i).print;.
Creation of new anonymous instances of objects at runtime (which
corresponds to using the
new constructor for classes in
languages such as C++), is typically achieved by new_
methods
which encapsulate the object constructor expressions. The name of
such a method usually starts with new_
followed by the name of
the (template) object whose instance is being created; sometimes a
suffix is used to distinguish between different versions. However,
this is merely a convention. (The only restriction imposed by the
language design is that no anonymous instances of abstract objects may
be created at runtime, since these objects are used to define the
interfaces and share common code between their subclasses.) Notable
exceptions from this convention are methods that construct
cons
cells,
pairs,
triples, and
quadruples, which
don't start with new_
for convenience. Here are some examples:
- initialize the created
m_vector with filler
method new_m_vector[T](size:int, filler:T):m_vector[T];
- use the
init closure to compute the initial values
method new_m_vector_init[T](size:int, init:&(int):T):m_vector[T];
Many operations which may produce an error or a special condition (e.g., indexing an array) take an optional last argument which is the closure to be invoked in such case. Thus, a programmer may either ignore the possibility of an error (which would halt the program) or handle the error condition (e.g., return a certain object when the array index is out of bounds). The default value of the closure invokes the error method, which prints a message, offers a debugging prompt, and then terminates the program. For example:
- invoke
if_absent if the key is not found
method fetch(t:table[`Key,`Value], key:Key, if_absent:&():Value):Value;