Dylan Design Notes

#19: Definitions are Declarative	(Change)

Version 1, March 1993
Copyright (c) 1993-1994, Apple Computer

This design note distinguishes definitions from other syntax forms, 
making module variable definition essentially a declarative 
operation, not a procedural one.  Definitions are restricted to 
appear only at the top level.  A given module variable can only be 
defined once, except for multiple define-method definitions with 
different specializers.  Definitions do not return values, since they 
cannot appear as argument expressions.

-------------------------------------------------------------------

On page 27 of the Dylan manual, define an outer expression to be an 
expression that is not a sub-expression of any expression.  Then 
define a top-level expression to be either an outer expression or a 
direct sub-expression of a begin syntax form that itself is a top-
level expression.  Note that a macro expands into a top-level 
expression if the macro invocation is itself a top-level expression.

On page 29, introduce a third kind of syntax form called a 
definition, introduced by a definition operator.  The definition 
operators in the book are  define, define-class, define-generic-
function, and define-method.  Change their documentation to say 
[Definition] instead of [Macro].

On page 30, restrict definitions to be top-level expressions.

On page 31, specify that a given module variable can only be defined 
once, except that multiple define-method definitions with different 
specializers are allowed, together with at most one define-generic-
function definition.

On page 31, remove indications of a value returned by define.  
Definitions do not have values since they cannot appear as argument 
expressions.

Modify footnote 9 on page 31, since define is no longer allowed 
inside a definition.

On page 39, change the first paragraph of the description of define-
generic-function to:

name should be a variable name.  It is defined as a read-only 
variable in the current module, containing a new generic function 
object, as specified by the parameter-list and options.

This eliminates all discussion of side effects in define-generic-
function.  Delete the second paragraph and any other indications of a 
value returned by define-generic-function.  Definitions do not have 
values since they cannot appear as argument expressions.

On page 40, replace the first four paragraphs of the description of 
define-method with the following, and eliminate any indication of a 
value returned by define-method.

define-method creates a method and adds it to the generic function in 
variable-name.  If the module variable variable-name  is not already 
defined, it is defined as with define-generic-function, with a 
parameter-list that has the same number of required parameters as 
parameter-list, contains #rest if and only if parameter-list  does, 
and contains #key (with no keys following it) if and only if 
parameter-list  contains #key.  Thus, define-method will create a new 
generic function or extend an old one, as needed.

This eliminates all discussion of side effects in define-method.

On page 51, remove the third and fourth paragraphs of the description 
of define-class.  This eliminates all discussion of side effects in 
define-class.  Also eliminate any  indications of a value returned by 
define-class.  Definitions do not have values since they cannot 
appear as argument expressions.

-------------------------------------------------------------------

Notes

The Dylan book describes definitions as if they were macros that 
expand into calls to operators available at run time such as set!, 
add-method, ensure-generic-function, etc.   This precludes the 
possibility of keeping the runtime free of overhead to support 
development operations such as adding new definitions or redefining 
existing definitions.  We prefer that definitions be static 
properties of a program, rather than side-effects that occur in some 
particular order.  This should allow the runtime to be smaller, and 
also allow for better compiler optimization because the structure of 
the program is more static.

We restrict definitions to be top-level expressions, because top-
level expressions are executed unconditionally, not inside of loops, 
and in a lexical environment containing only module variables, which 
makes them sufficiently static for our purposes.

The revised language specification does not allow redefinition and 
thus does not have to define the semantics of redefinition.  
Presumably most development environments that feature incremental 
compilation will support redefinition as a programmer operation, not 
as part of the program.

Allowing definitions to be top-level expressions, rather than just 
outer expressions, makes it possible for a macro to expand into 
several definitions and other expressions by enclosing them in a 
begin syntax form.

Additional definition operators might be added in the future, for 
example for macros, modules, constants, or things associated with 
sealing.  Defining a macro would be a definition because the name it 
introduces is scoped like a module variable even if it is not a 
true module variable.  This language change is intended to include 
all future definition operators. 
