[Next] [Previous] [Up] [Top] [Contents] [Index]

14 The Built-In Macros and Special Operators

Definitions

Definitions are used to declare the overall structure of a program. They often define one or more module bindings, but do not always do so. Definitions can only appear at top level in a program. Definitions do not return values.
Definitions (continued)
Macro DescriptionPage
define variable Defines and initializes a variable binding in the current module.360
define constant Defines and initializes a constant binding in the current module.361
define generic Defines a constant binding in the current module and initializes it to a new generic function.362
define method Adds a method to a generic function, and potentially defines a constant binding in the current module containing a new generic function.363
define class Defines a constant binding in the current module and initializes it to a new class.364
define module Defines and names a module, describing the imports and exports of the module.367
define library Defines and names a library, describing the imports and exports of the library.372
define domain Restricts the ways in which a generic function and set of types can be extended, thereby enabling additional error checking and compiler optimization.374
define macro Defines a constant module binding containing a macro.375

define variable [Definition]


Defines and initializes a variable binding in the current module.

Macro Call:
define { adjective }* variable variables = init

Arguments:
adjective unreserved-namebnf. The adjectives allowed are implementation dependent.

variables
variablebnf | ( variable-listbnf )

init
expressionbnf

Description:
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 constant [Definition]


Defines and initializes a constant binding in the current module.

Macro Call:
define { adjective }* constant constants = init

Arguments:
adjective unreserved-namebnf. The adjectives allowed are implementation dependent.

constants
variablebnf | ( variable-listbnf )

init
expressionbnf

Description:
Creates constant bindings in the current module.

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 generic [Definition]


Defines a constant binding in the current module and initializes it to a new generic function.

Macro Call:
define { adjective }* generic name parameter-list [ options ]

Arguments:
adjective 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.

name
variable-namebnf

parameter-list
( [ parametersbnf ] ) [ => values ]

options
comma-property-listbnf

values
variablebnf | ( [ values-listbnf ] )

Description:
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 method [Definition]


Adds a method to a generic function, and potentially defines a constant binding in the current module containing a new generic function.

Macro Call:
define { adjective }* method name parameter-list
[ body ]
end [ method ] [ name ]

Arguments:
adjective unreserved-namebnf. The allowed adjective is inert. Additional implementation-defined adjectives may be supported.

name
variable-namebnf

parameter-list
parameter-listbnf

body
bodybnf

Description:
define method creates a method and adds it to the generic function in name. If the module binding name is not already defined, it is defined as with define generic. Thus, define method will create a new generic function or extend an old one, as needed.

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 [Definition]


Defines a constant binding in the current module and initializes it to a new class.

Macro Call:
define { class-adjective }* class name ( { superclass } ,+ )
{ slot-spec | init-arg-spec | inherited-slot-spec } ;*
end [ class ] [ name ]

Arguments:
class-adjective
unreserved-namebnf. The allowed adjectives are abstract, concrete, primary, free, sealed, and open. Additional implementation-dependent class-adjectives may be supported.

name
variable-namebnf

superclass
expressionbnf

slot-spec
{ slot-adjective }* [ allocation ]
slot getter-name [ :: type ] [ init-expression ]
{ , slot-option }*

init-arg-spec
[ required ] keyword symbolbnf [ init-expression ]
{ , init-arg-option }*

inherited-slot-spec

inherited slot getter-name [ init-expression ]
{ , inherited-option }*

slot-adjective
unreserved-namebnf. Supported slot-adjectives are constant and inert. Additional implementation-dependent slot-adjectives may be supported.

allocation
unreserved-namebnf. Supported allocations are instance, class, each-subclass, and virtual. Additional implementation-defined allocations may be supported.

getter-name
variable-namebnf

type
operandbnf

init-expression
= expressionbnf

slot-option
setter-option |
init-keyword-option |
required-init-keyword-option |
init-value-option |
init-function-option |
type-option

init-arg-option
type-option |
init-value-option |
init-function-option

inherited-option
init-value-option |
init-function-option

setter-option
setter: { variable-namebnf | #f }

init-keyword-option
init-keyword: symbolbnf

required-init-keyword-option
required-init-keyword: symbolbnf

init-value-option
init-value: expressionbnf

init-function-option
init-function: expressionbnf

type-option
type: expressionbnf

Description:
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 [Definition]


Defines and names a module, describing the imports and exports of the module.

Macro Call:
define module module-name
{ export-clause | create-clause |use-clause } ;*
end [ module ] [ module-name ]

Arguments:
module-name namebnf

export-clause
export { ordinary-namebnf } ,*

create-clause
create { ordinary-namebnf } ,*

use-clause
use used-module { ,option }*

used-module
ordinary-namebnf

option
import-option |

exclude-option |

prefix-option |

rename-option |

export-option

import-option
import: all | { { variable-spec } ,* }

variable-spec
namebnf [ => namebnf ]

exclude-option
exclude: { { namebnf } ,* }

prefix-option
prefix: string-literalbnf

rename-option
rename: { { namebnf => namebnf } ,* }

export-option
export: all | { { namebnf } ,* }

Description:
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.

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 module
The 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 [Definition]


Defines and names a library, describing the imports and exports of the library.

Macro Call:
define library library-name
{ export-clause | use-clause } ;*
end [ library ] [ library-name ]

Arguments:
library-name namebnf

use-clause
use used-library { ,option }*

export-clause
export { ordinary-namebnf } ,*

used-library
ordinary-namebnf

option
import-option |

exclude-option |

prefix-option |

rename-option |

export-option

import-option
import: all | { { module-spec } ,* }

module-spec
namebnf [ => namebnf ]

exclude-option
exclude: { { namebnf } ,* }

prefix-option
prefix: string-literalbnf

rename-option
rename: { { namebnf => namebnf } ,* }

export-option
export: all | { { namebnf } ,* }

Description:
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.

define inert domain [Definition]


Restricts the ways in which a generic function and set of types can be extended, thereby enabling additional error checking and compiler optimization.

Macro Call:
define inert domain generic-function ( { type } ,* )

Arguments:
generic-function
variable-namebnf

type
expressionbnf

Description:
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 [Special Definition]


Defines a constant module binding containing a macro.

Macro Call:
define macro macro-definition

Arguments:
macro-definition
macro-definitionbnf

Description:
See Chapter 10, "Macros," for a complete description of the macro system.

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.


Dylan Reference Manual - 17 OCT 1995
[Next] [Previous] [Up] [Top] [Contents] [Index]

Generated with Harlequin WebMaker