14 The Built-In Macros and Special Operators
define { adjective
}* variable
variables =
init
unreserved-namebnf
. The adjectives allowed are implementation dependent.
variablebnf | ( variable-listbnf )
expressionbnf
define variable
creates variable bindings in the current module.
The values returned by init are used to initialize the bindings. The first value returned is bound to the first variable, the second value to the second variable, etc. The last variable may be preceded by #rest
, in which case it is bound to a sequence containing all the remaining values.
If more than one binding is defined, the variables are enclosed in parentheses and separated by commas.
define variable *elapsed-time* = 0; define variable (*whole-part*, *remainder*) = truncate(*amount*); define variable (*first-value*, #rest *rest-values*) = get-inital-orders();Module bindings may be specialized. This ensures that their value will always be of a given type. An attempt to initialize or assign the binding to a value not of that type will signal an error of type
<type-error>
.
define variable *elapsed-time* :: <integer> = 0; define variable *front-window* :: union (<window>, singleton(#f)) = initial-front-window(); define variable (*whole-part* :: <integer>, *remainder* :: <real>) = truncate(*amount*);
define { adjective }* constant
constants =
init
unreserved-namebnf
. The adjectives allowed are implementation dependent.
variablebnf | ( variable-listbnf )
expressionbnf
The values returned by init are used to initialize the constant bindings. The first value returned is bound to the first constant, the second value to the second constant, etc. The last constant may be preceded by #rest
, in which case it is bound to a sequence containing all the remaining values.
If more than one constant is defined, the constants are enclosed in parentheses and separated by commas.
define constant $start-time = get-current-time(); define constant $pi = 3.14159; define constant ($whole-pie, $piece-pie) = truncate($pi);Module constants may be specialized. This ensures that their value is of a given type. An attempt to initialize the constant to a value not of that type will signal an error of type
<type-error>
.
define constant $start-time :: <integer> = get-current-time();A constant binding cannot be assigned a new value. However, the object which is the value of the constant binding is not necessarily itself immutable. For example, if a constant binding contains a sequence, the elements of the sequence may be settable.
define { adjective }* generic name parameter-list [ options ]
unreserved-namebnf
. The allowed adjectives are sealed
and open
. These adjectives are mutually exclusive. The default is sealed
. Additional implementation-defined adjectives may be supported.
variable-namebnf
( [ parametersbnf ] ) [ => values ]
comma-property-listbnf
variablebnf | ( [ values-listbnf ] )
define generic
is used to define generic functions.It creates a constant module binding with the name name, and initializes it to a new generic function described by the adjectives, parameter-list and options.
The adjectives specify whether the generic function is sealed. A complete description of generic function sealing is given in"Declaring Characteristics of Generic Functions" on page 133.
The parameter-list specifies the parameters and return values of the generic function and thereby constrains which methods may be added to it. For a complete description of these constraints, see "Parameter List Congruency" on page 91.
The options are alternating keywords and values. No options are defined by the language. They may be supplied by individual implementations.
The following example defines a generic function of two required arguments and one return value. All methods added to the generic function must also take two arguments and return one value. The first argument will always be specialized to a subtype of <animal>
, the second argument will always be specialized to a subtype of <number>
, and the return value will always be specialized to a subtype of <number>
.
define generic cut-hair (subject :: <animal>, new-length :: <number>) => (new-length :: <number>)The use of the same name for a parameter and return value indicates that the parameter is returned as the value. This is only a convention; it is not enforced by the language.
The following example defines a generic function with one required parameter and one mandatory keyword parameter, strength:
. Methods added to the generic function must have one required parameter, they must accept keyword arguments, and they must permit the keyword argument strength:
.
define generic brew (brand :: <coffee-brand>, #key strength) => (coffee :: <coffee>)
define { adjective }* method name parameter-list
[ body ]
end [ method ] [ name ]
unreserved-namebnf
. The allowed adjective is inert
. Additional implementation-defined adjectives may be supported.
variable-namebnf
parameter-listbnf
bodybnf
The adjective allows a sealing declaration to be made about the generic function to which the method is added. The effect of this adjective is described in "Abbreviations for Define Inert Domain" on page 136.
The parameter-list describes the parameters and return values of the method, including their number and type. The method can be called only with arguments that match the types of the parameters, and the method will always return values in the quantity and typed declared. Methods added to a generic function must have parameter lists that are congruent with the generic function's parameter list. A complete description of parameter lists is given in "Parameter Lists" on page 82.
When the method is called, new local bindings are created for the parameters, initialized to the arguments of the call. The body is then executed in the environment containing these bindings.
define method tune (device :: <radio>) => (station :: <station>) // method body goes here end method tune
define { class-adjective }* class name ( { superclass } ,+ )
{ slot-spec | init-arg-spec | inherited-slot-spec } ;*
end [ class ] [ name ]
unreserved-namebnf
. The allowed adjectives are abstract
, concrete
, primary
, free
, sealed
, and open
. Additional implementation-dependent class-adjectives may be supported.
variable-namebnf
expressionbnf
{ slot-adjective }* [ allocation ]
slot getter-name [ :: type ] [ init-expression ]
{ , slot-option }*
[ required ] keyword symbolbnf [ init-expression ]
{ , init-arg-option }*
inherited slot getter-name [ init-expression ]
{ , inherited-option }*
unreserved-namebnf
. Supported slot-adjectives are constant
and inert
. Additional implementation-dependent slot-adjectives may be supported.
unreserved-namebnf
. Supported allocations are instance
, class
, each-subclass
, and virtual
. Additional implementation-defined allocations may be supported.
variable-namebnf
operandbnf
= expressionbnf
|
init-keyword-option |
required-init-keyword-option |
init-value-option |
init-function-option |
type-option
|
init-value-option |
init-function-option
|
init-function-option
setter: { variable-namebnf | #f }
init-keyword: symbolbnf
required-init-keyword: symbolbnf
init-value: expressionbnf
init-function: expressionbnf
type: expressionbnf
define class
is used to define classes.It creates a constant module binding with the name name, and initializes it to a new class.
The class-adjectives provide sealing information about the class. Among the adjectives, abstract
and concrete
are mutually exclusive, primary
and free
are mutually exclusive, and sealed
and open
are mutually exclusive. Additional implementation-defined adjectives may be supported. See "Declaring Characteristics of Classes" on page 132 for a complete description of these adjectives.
The superclasses are the classes from which the new class directly inherits. The rules of inheritance are described in "Class Inheritance" on page 51 and "Computing the Class Precedence List" on page 52.
The init-expression, required-init-keyword-option, init-value-option, and init-function-option are all mutually exclusive in a single slot-spec, init-arg-spec, or inherited-slot-spec.
Each slot-spec describes a slot specification in the class. Slot specifications are described in "Slot Specifications" on page 57
Each init-arg-spec describes the handling of an initialization argument specification of the class. Initialization argument specifications are described in "Initialization Argument Specifications" on page 67.
Each inherited-slot-spec describes an inherited slot specification of the class. Inherited slot specifications are described in "Inherited Slot Specifications" on page 66.
define module module-name
{ export-clause | create-clause |use-clause } ;*
end [ module ] [ module-name ]
namebnf
export { ordinary-namebnf } ,*
create { ordinary-namebnf } ,*
use used-module { ,option }*
ordinary-namebnf
|
|
|
|
import: all | { { variable-spec } ,* }
namebnf [ => namebnf ]
exclude: { { namebnf } ,* }
prefix: string-literalbnf
rename: { { namebnf => namebnf } ,* }
export:
all | { { namebnf } ,* }
define module
defines a module with the given name. It describes which modules are used by the module being defined, which bindings are imported from the used modules, and which bindings are exported by the module being defined.Circular use relationships among modules are not allowed. The graph of the module-uses-module relation must be directed and acyclic.
Like other definitions, module definitions are only allowed at top level. Like all constituents, module definitions are contained in a module. The names of bindings being imported and exported in a module definition refer to bindings in the module being defined and the modules being used. These are not affected by the module which contains the module definition.
There is no prohibition against macros which expand into module definitions.
all
, or a series of comma-delimited variable-specs enclosed in curly braces. The default is all
, indicating that all bindings should be imported. If a series of variable-specs is specified, only the indicated variables are imported.
all
.
all
, or a series of comma-delimited names enclosed in curly braces. Each name is the name of the binding in the module being defined as well as the name under which it will be exported. (There is no option to rename on export) Each binding indicated must have been imported by this use clause. It is allowed for the same name to appear more than once, as this is sometimes useful for documentation purposes. all indicates that all the bindings imported by this use clause should be exported. The default value for this option is the empty set.
define module graphics use dylan; create draw-line, erase-line, invert-line, skew-line frame-rect, fill-rect, erase-rect, invert-rect; end module graphics; define module lines use dylan; use graphics, import: {draw-line, erase-line, invert-line, skew-line}; end module lines; define module rectangles use dylan; use graphics, prefix: "graphics$", exclude: {skew-line}; end module rectangles; define module dylan-gx use dylan, export: all; use graphics, rename: {skew-line => warp-line}, export: all; end module dylan-gx;The modules created by these module declarations would have access to bindings with the following names:
graphics draw-line erase-line invert-line skew-line frame-rect fill-rect erase-rect invert-rect plus all the bindings in the Dylan module lines draw-line erase-line invert-line skew-line plus all the bindings in the Dylan module rectangles graphics$draw-line graphics$erase-line graphics$invert-line graphics$frame-rect graphics$fill-rect graphics$erase-rect graphics$invert-rect plus all the bindings in the Dylan module dylan-gx draw-line erase-line invert-line warp-line frame-rect fill-rect erase-rect invert-rect plus all the bindings in the Dylan moduleThe
lines
and rectangles
modules do not export any variables. They are presumably used to provide definitions for the variables created and exported by the graphics
modules. The difference between the graphics
module and the dylan-gx
module is that one variable is renamed, and the dylan-gx
module exports the variables which it imports from the dylan module, while the graphics
module does not.
define library library-name
{ export-clause | use-clause } ;*
end [ library ] [ library-name ]
namebnf
use used-library { ,option }*
export { ordinary-namebnf } ,*
ordinary-namebnf
|
|
|
|
import: all | { { module-spec } ,* }
namebnf [ => namebnf ]
exclude: { { namebnf } ,* }
prefix: string-literalbnf
rename: { { namebnf => namebnf } ,* }
export:
all | { { namebnf } ,* }
define library
defines a library with the given name. It describes which libraries are used by the library being defined, which modules are imported from the used libraries, and which modules are exported by the library being defined.Circular use relationships among libraries are not allowed. The graph of the library-uses-library relation must be directed and acyclic.
Like other definitions, library definitions are only allowed at top level. Like all constituents, library definitions are contained in a module. The names of modules being imported and exported by a library definition do not refer to bindings, and are not affected by the environment in which the library definition occurs.
There is no prohibition against macros which expand into library definitions.
all
, or a series of comma-delimited module-specs enclosed in curly braces. The default is all
, indicating that all modules should be imported. If a series of module-specs is specified, only the indicated modules are imported.
all
.
all
, or a series of comma-delimited names enclosed in curly braces. Each name is the name of the module in the library being defined as well as the name under which it will be exported. (There is no option to rename on export) Each module indicated must have been imported by this use clause. It is allowed for the same name to appear more than once, as this is sometimes useful for documentation purposes. all indicates that all the modules imported by this use clause should be exported. The default value for this option is the empty set.
define inert domain
generic-function ( { type } ,* )
variable-namebnf
expressionbnf
define inert domain
seals the specified generic-function over the domain indicated by the types. For a complete description of the rules governing define inert domain
and the implications of a define inert domain
definition, see "Define Inert Domain" on page 133.
define macro macro-definition
macro-definitionbnf
Note that define macro
is not a defining macro but a special definition. It is not named by a binding, and so it cannot being excluded or renamed using module operations.
Generated with Harlequin WebMaker