Define

The define special form has many uses, depending on the context where the form is used, and the syntax employed.

Definition of a Function:

This form of define binds a lambda function to an identifier; it is the chief way functions are defined in MOSVM.

Usage:

(define (func-name [arg ...] [. rest]) stmt ...)

Example:

(define (write-line data)
   (write data)
   (write *line-sep*))

Definition of a Method:

This form may either extend an existing definition to form a multimethod with support for a new method, or will create a new multimethod that only supports the specified method. This employs make-multimethod and the ? special form to layer the new method on top of older functions, primitives and multimethods.

For a definition to be considered a method definition, it must contain at least one argument of the form: (arg-type arg-name)

Usage:

(define (func-name [arg ...] [. rest]) stmt ...)

Example:

(define (write-line data (<port> port))
   (write data port)
   (write *line-sep* port))

If this form occurred directly after the example in "Definition of a Function", above, it would replace the function defined with a multimethod that supported (write data port) as well as (write data).

Definition of a Variable:

The third common usage of define is to declare a variable and assign a value to it. MOSVM regards the re-definition of a variable in the same scope to be identical to using set!.

Usage:

(define var-name expr)

Example:

(define magic-word "xyzzy")

Definition in the Global Scope:

If a define occurs outside of any scope, in the source of a program or module, and the program lacks any export forms, it is considered to be a global definition. The definition will be shared across all programs and processes, in the so-called global environment.

Example of Global and Module Scope Mixed:

(module "example/square")

(define (req-number value)
  (unless (integer? value)
    (error 'args "value must be an integer" value)))

(define (square root)
  (req-number root)
  (* root root))

(export square)

In the above example, the helper function "req-number" is not exported by the square module -- it is considered to be in the module scope, explained in "Definition in the Module Scope"; however "square" is placed in the global scope.

Definition in the Module Scope:

A definition that occurs outside of a function or method, in a program or module that contains export forms, that is not listed in an export form, is considered a "module" scope definition, will persist only during the execution of the program
and will only be accessible by the module itself.

Definition in the Local Scope:

A definition that occurs within a function or method is considered a local definition. It is only accessible by other expressions adjacent to the definition, or within blocks of code adjacent to that definition.

In MOSVM, this form is often preferable to the let special form -- it is considered much easier to understand for programmers who come from conventional languages.

Unlike Scheme, MOSVM permits the mixture of local definitions and statements, like the following:

Example of Locals Mixed With Statements:

(define (reverse src-list)
  (define dest-tc (make-tc))

  (tc-splice! src-tc src-list)
  (define src-tc (make-tc)) ;; Illegal in Scheme

  (until (tc-empty? src-tc)
    (tc-prepend! dest-tc (tc-next! src-tc)))

  (tc->list dest-tc))