Previous Home Contents Next

Chapter 11: Generic tie-ins

11.1 Literals

11.2 Program-defined tests

11.3 Generator

11.4 Apply

11.5 Set!

11.6 Bracket

11.7 Coerce

Several syntactic constructs are defined in terms of function application in Aldor:

This allows user programs to define how these syntactic constructs behave in a particular lexical context. The function calls themselves are treated as standard function calls, so the normal rules apply.



11.1 : Literals

Types provide meanings for literal constants by defining functions named "integer", "float" or "string" taking values of type Literal. The type Literal represents the source text of the particular literal. Valid literal values are described in section 5.2.

The meaning of string-style literals is determined by what operations

are visible, where X may be any type. Both in #include "aldor" and #include "axiom" the type String provides string-style literals.

Both integer and floating point literals are passed in the same way, so it is legal to call the function string on them. This can be used to allow numbers to be parsed as strings. For example, the function scanNumber, from NumberScanPackage in the Aldor base library, converts a string into an element of an arithmetic type. The following example is from the implementation of arbitrary precision floats in theAldor base library.

Note that the literal "l" is converted to a string, and then scanNumber is called on the result to form a new value.



11.2 : Program-defined tests

There are several types of expression in which a condition controls the evaluation of an Aldor program:

In many situations, a value can be treated as a condition, even though it may not be a value from the "Boolean" type. Aldor allows these to be treated as logical values in the above constructs. If a condition above produces a value of type T, different from Boolean, and there is a single function "test: T -> Boolean" in scope, then that "test" function is implicitly applied to the condition value to determine the outcome of the test. For example:





11.3 : Generator

If an expression traversed by a "for" iterator does not evaluate to a Generator value, then the operator "generator" is implicitly applied to the expression. This makes loops more readable if the for is traversing, for example, a list or an array:

The "for elem in ls repeat ..." of the previous example is equivalent to:

When List Integer is imported, then the application:

comes into the current scope.



11.4 : Apply

In the absence of an explicit function named "a", the application "a(b)" is treated as a call to the function "apply" with the first argument being taken to be "a", and the remaining arguments being taken from the arguments to the original application. Example:

For example, consider a matrix domain over a ring, R. A desirable syntax for retrieving elements of a particular matrix might be:

where a and b are integer indices for the matrix. To achieve this, a matrix domain would export a function with signature:

The function is defined in the normal way.



11.5 : Set!

If the left hand side of an assignment is an application, the assignment is treated as an application of the operator set! to the operator of the left hand side, the operands of the left hand side and the right hand side.

f(a,b) := E becomes set!(f,a,b,E)
f a := E becomes set!(f,a,E)
f.a := E becomes set!(f,a,E)
f.a.b := E becomes set!(f.a,b,E)

As an example, consider the matrix domain above. We would like to assign into the matrix using a syntax like:

To achieve this, the domain should export a function with signature:

As this is just a normal function, there are no restrictions on the return type or value. In this case a value from R is returned, and the description indicates which. Note that the description is purely for documentation purposes, and not used to interpret the program.



11.6 : Bracket

An expression of the form:

is treated as an application of the operator "bracket" to Expr.

Example:

As can be seen above, this is a useful syntax for creating aggregates of various types. The value passed to the "bracket" function in this case is a tuple of the three values 1, 2 and 3.



11.7 : Coerce

An expression of the form:

is treated as an application of the operator coerce to Expr and restricted to be of type T:

This allows types to define their own mechanisms for converting between types, and enables types to do appropriate error checking.


Previous Home Contents Next