The defstar Reference Manual

Table of Contents

Next: , Previous: , Up: (dir)   [Contents][Index]

The defstar Reference Manual

This is the defstar Reference Manual, version 1.0.0, generated automatically by Declt version 2.4 "Will Decker" on Wed Jun 20 11:41:13 2018 GMT+0.


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

1 Introduction

The DEFSTAR library

Defstar is a collection of Common Lisp macros that can be used in place of defun, defmethod, defgeneric, defvar, defparameter, flet, labels, let* and lambda. Each macro has the same name as the form it replaces, with a star added at the end, e.g. defun*. (the exception is the let* replacement, which is called *let).

The macros allow:

See below for a detailed discussion of each macro, with usage examples.

Defstar's home is at http://bitbucket.org/eeeickythump/defstar/.

Installation requires ASDF or Quicklisp. Defstar does not depend on any other libraries.

Function definitions

The function-defining macros (defun*, flet*, labels*, lambda*) work the same as their normal counterparts, with the following exceptions:

Examples of function definitions

Define a simple function that adds two numbers, both of which are declared to be real.

:::cl
(defun* sum ((a real) (b real))
   (+ a b))

Now also declare that the function returns a real.

:::cl
(defun* (sum -> real) ((a real) (b real))
   (+ a b))

Another way of declaring the function's return type.

:::cl
(defun* sum ((a real) (b real))
   (:returns real)
   (+ a b))

We want to ensure that a and b are never negative. One way is to alter the type declarations:

:::cl
(defun* (sum -> (real 0)) ((a (real 0)) (b (real 0)))
   (+ a b))

Another way is to define a new type:

:::cl
(deftype natural () '(real 0))
(defun* (sum -> natural) ((a natural) (b natural))
 (+ a b))

Another way is to use assertions:

:::cl
(defun* (sum -> real (>= result 0)) ((a real (>= a 0)) (b real (>= b 0)))
   (+ a b))

Or:

:::cl
(defun* sum ((a real (>= a 0)) (b real (>= b 0)))
   (:returns real (>= result 0))
   (+ a b))

Or, using the feature that the names of single-argument predicate functions can be used as assertions:

:::cl
(defun* (naturalp -> boolean) ((x real))
   (not (minusp x)))
...
(defun* (sum -> real naturalp) ((a real naturalp) (b real naturalp))
   (+ a b))

Another approach is to use :pre and :post clauses. Each contains one or more forms, ALL of which must evaluate to non-nil. Within :post forms, result is bound to the value that the function or form is about to return.

:::cl
(defun* (sum -> real) ((a real) (b real))
   (:pre (>= a 0) (>= b 0))
   (:post (>= result 0))
   (+ a b))

Ignoring arguments

Here is a simple function that ignores all its arguments after the first:

:::cl
(defun* my-first (item &rest _)
  item)

Multiple return values

A function that returns multiple values.

:::cl
(defun* (floor -> (values integer integer)) ((n real) (d real))
   (cl:floor n d))

It is possible to use assertions with functions that return multiple values. When a function is declared to return multiple values, result will be bound to a list of those values.

:::cl
(defun* floor ((n real) (d real))
   (:returns (values integer integer)
            (< (second result) (first result)))
   (cl:floor n d))

To declare that a function returns an unspecified number of values, of unspecified types:

:::cl
(defun* (floor -> (values)) ((n real) (d real))
   ...)

No return values

:::cl
(defun* (print-message -> (values)) ((fmt string) &rest args)
   (apply #'format t fmt args)
   (values))

The type specifier :void has been defined as a synonym for (values):

:::cl
(defun* (print-message -> :void) ((fmt string) &rest args)
   (apply #'format t fmt args)
   (values))

Type declarations for &rest, &optional and keyword arguments

The type of a &rest argument can be declared. The declaration refers to the types of each element in the list of arguments stored in the &rest argument.

:::cl
(defun* (+ -> real) (&rest (numbers real))
   (apply #'cl:+ numbers))

A more complicated lambda list. Note that the function and its first argument do not have type declarations. Also note the syntax of typed keyword arguments:

((var TYPE [ASSERTION]) DEFAULT [SUPPLIEDP])

Note that &optional arguments use the same syntax.

:::cl
(defun* my-find (item (seq sequence) &key (from-end boolean)
                 ((test (or null (function (t)))) nil)
                 ((test-not (or null (function (t)))) nil)
                 ((key (or null (function (t)))) nil)
                 (start fixnum) (end fixnum))
   ...function body...)

defmethod* and defgeneric*

Here is an example of method definition. All the arguments in the arglist are normal 'specialised' arguments like you would usually find in a method definition. The form still allows you to include an assertion with each argument, however (plusp in this case).

:::cl
(defmethod* (cell-value -> real) :around ((sheet <Sheet>)
                                          (x integer plusp) (y integer plusp))
    ...)

Note that when you declare a return type for a method, the method body will perform type-checking, but no toplevel declaim form will be generated.

CLOS function dispatch based on classes is limited; you cannot specialise on user-defined types unless they are proper classes, for example. You may therefore sometimes want to declare that a method's argument is of a particular type, as well as declaring its class for specialisation as you normally would.

Here is an example. Note the similarity to the syntax for keyword arguments.

:::cl
(defmethod* (cell-value -> real) :around ((sheet <Sheet>)
                                          ((x natural plusp) integer)
                                          ((y natural plusp) integer))
   ...)

An example of defgeneric*, mainly useful to declare the return type of a set of methods. Note the documentation string can appear after the argument list, similar to defun.

:::cl
(defgeneric* (cell-value -> real) (sheet x y)
  "Return the value of the cell at coordinates X,Y in SHEET.")

defgeneric* can also be used to declare types of arguments. Be careful that these don't clash with specialisers in method definitions.

:::cl
(defgeneric* (cell-value -> real) (sheet (x natural) (y natural)))

defvar* and defparameter*

Used to declare the types of global variables.

:::cl
(defvar* (*user-name* string) "Bob")


:::cl
(defparameter* (*file-position* (integer 0)) 0)

*let

This statement behaves like let*, with the following differences:

For example,

:::cl
(*let ((name "Bob")
       (age integer 40)
       (sex (member :male :female) :male)
       ((num street &optional suburb) address)
       ((:values (day fixnum) month year) birthday))
   ...body...)

Expands to:

:::cl
(let ((name "Bob"))
  (let ((age 40))
    (declare (integer age))
    (let ((sex :male))
      (declare ((member :male :female) sex))
      (destructuring-bind
          (num street &optional suburb) address
        (multiple-value-bind (day month year) birthday
          (declare (fixnum day))
          ...body...)))))

Arguments can also be auto-ignored within *let statements by naming them _:

:::cl
(*let (((top . _) list))
   (print top))

nlet

This statement is identical to let, except that a name comes before the binding clauses. Within the body of the nlet, this name can be called like a function, with arguments corresponding to the local variables bound in the nlet statement. Calling this function returns execution to the start of the nlet body, but the local variables will be bound to the values given to the function rather than the values specified in the nlet binding clauses.

nlet is intended to provided the same functionality as Scheme's named let. The macro does not perform tail call optimisation itself. However all modern Common Lisp implementations will perform TCO on the generated code (I am assured).

Type declaration versus type checking

Technically, declare, declaim and the like do not actually check that values stored in the associated variables conform to the declared type. They merely constitute a promise by the programmer that only values of the specified type will be stored there. The consequences of storing a string in a variable that is declared to be of type integer, are technically 'undefined'.

In practice, most modern Common Lisp implementations perform type-checking based on declaration information, especially when the safety setting is high.

Defstar allows you to force lisp to perform type checking based on declarations. If you set the global variable *check-argument-types-explicitly?* to non-nil, check-type forms will be inserted in the body of each function or method, causing an error to be raised if a value does not match its declared type.

Limitations

Definitions of setf methods cannot include return type declarations in the method 'header'. The return type can still be declared using a (:returns ...) form.

Incorrect:

:::cl
(defmethod (setf (foo -> integer)) (...args...)
   ...)

Correct:

(defmethod (setf foo) (...args...)
   (:returns integer)                  ; legal
   ...)

Syntax highlighting of Defstar macros in Emacs

Put the following code in your .emacs if you want defvar* and other forms to appear in the same face as their normal counterparts, and if you want their docstrings to also be correctly identified as docstrings rather than normal strings.

:::cl
;; fontify doc strings in correct face
;; lisp-mode already fontifies 'defun*' correctly
(put 'defvar*   'doc-string-elt 3)
(put 'defparameter*   'doc-string-elt 3)
(put 'lambda*   'doc-string-elt 2)

(defvar *lisp-special-forms*
(regexp-opt '("defvar*"
              "defconstant*"
              "defparameter*"
              "defgeneric*"
              "defmethod*"
              "lambda*"
              "flet*"
              "labels*") 'words))
(font-lock-add-keywords 'lisp-mode
  `((,*lisp-special-forms* . font-lock-keyword-face)))

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

2 Systems

The main system appears first, followed by any subsystem dependency.


Previous: , Up: Systems   [Contents][Index]

2.1 defstar

Author

Paul Sexton <eeeickythump@gmail.com>

Description

defstar: macros allowing easy inline type declarations for variables and and function return values.

Version

1.0.0

Source

defstar.asd (file)

Component

defstar.lisp (file)


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

3 Files

Files are sorted by type and then listed depth-first from the systems components trees.


Previous: , Up: Files   [Contents][Index]

3.1 Lisp


Next: , Previous: , Up: Lisp files   [Contents][Index]

3.1.1 defstar.asd

Location

defstar.asd

Systems

defstar (system)

Packages

defstar-system


Previous: , Up: Lisp files   [Contents][Index]

3.1.2 defstar/defstar.lisp

Parent

defstar (system)

Location

defstar.lisp

Packages

defstar

Exported Definitions
Internal Definitions

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

4 Packages

Packages are listed by definition order.


Next: , Previous: , Up: Packages   [Contents][Index]

4.1 defstar-system

Source

defstar.asd

Use List

Previous: , Up: Packages   [Contents][Index]

4.2 defstar

* Description

DEFSTAR is a collection of macros that can be used in place of =DEFUN, DEFMETHOD, DEFGENERIC, DEFVAR, DEFPARAMETER, FLET, =LABELS=, =LET*= and =LAMBDA=. Each macro has the same name as the form it replaces, with a star added at the end, e.g. =DEFUN*=. (The exception is the =LET*= replacement, which is called =*LET=).

The macros allow:
- easy inclusion of type declarations within lambda lists
- easy inclusion of return type declarations in function and method definitions - easy declaration of variables as ’ignored’, by the use of ’_’ as a placeholder in argument lists.
- easy inclusion of assertions for each argument and for the function’s
return value, thus allowing simple programming by contract.

See [[defun*]] and [[defvar*]] for a detailed description of syntax. See also the examples below.

DEFSTAR’s home is at:
- [[http://bitbucket.org/eeeickythump/defstar/]]

Installation requires [[http://common-lisp.net/project/asdf/][ASDF]]. DEFSTAR does not depend on any other libraries.

* Examples of DEFUN* and DEFMETHOD* usage
;;; ;; Define a simple function that adds two numbers, both of which
;;; ;; are declared to be real.
;;; (defun* sum ((a real) (b real))
;;; (+ a b))
;;;
;;; ;; Now also declare that the function returns a real.
;;; (defun* (sum -> real) ((a real) (b real))
;;; (+ a b))
;;;
;;; ;; Another way of declaring the function’s return type.
;;; (defun* sum ((a real) (b real))
;;; (:returns real)
;;; (+ a b))
;;;
;;; ;; We want to ensure that a and b are never negative.
;;; ;; One way is to alter the type declarations:
;;; (defun* (sum -> (real 0)) ((a (real 0)) (b (real 0)))
;;; (+ a b))
;;;
;;; ;; Another way is to define a new type:
;;; (deftype natural () ’(real 0))
;;; (defun* (sum -> natural) ((a natural) (b natural))
;;; (+ a b))
;;;
;;; ;; Another way is to use assertions:
;;; (defun* (sum -> real (>= result 0)) ((a real (>= a 0)) (b real (>= b 0))) ;;; (+ a b))
;;;
;;; ;; Or:
;;; (defun* sum ((a real (>= a 0)) (b real (>= b 0)))
;;; (:returns real (>= result 0))
;;; (+ a b))
;;;
;;; ;; Or, using the feature that the names of single-argument predicate
;;; ;; functions can be used as assertions:
;;; (defun* (naturalp -> boolean) ((x real))
;;; (not (minusp x)))
;;; ...
;;; (defun* (sum -> real naturalp) ((a real naturalp) (b real naturalp))
;;; (+ a b))
;;;
;;; ;; Another approach is to use :pre and :post clauses. Each contains one ;;; ;; more forms, ALL of which must evaluate to non-nil. Within :post
;;; ;; forms, result is bound to the value that the function or form
;;; ;; is about to return.
;;; (defun* (sum -> real) ((a real) (b real))
;;; (:pre (>= a 0) (>= b 0))
;;; (:post (>= result 0))
;;; (+ a b))
;;;
;;; ;; A function that returns multiple values.
;;; (defun* (floor -> (values integer integer)) ((n real) (d real))
;;; (cl:floor n d))
;;;
;;; ;; Example of ignoring arguments
;;; (*let (((top . _) list))
;;; (print top))
;;;
;;; ;; It is possible to use assertions with functions that return
;;; ;; multiple values. When a function is declared to return multiple
;;; ;; values, RESULT will be bound to a LIST of those values.
;;; (defun* floor ((n real) (d real))
;;; (:returns (values integer integer)
;;; (< (second result) (first result)))
;;; (cl:floor n d))
;;;
;;; ;; To declare that a function returns an unspecified number of
;;; ;; values, of unspecified types:
;;; (defun* (floor -> (values)) ((n real) (d real))
;;; ...)
;;;
;;; ;; The type of a &REST argument can be declared. The declaration
;;; ;; refers to the types of each element in the list of arguments
;;; ;; stored in the &REST argument.
;;; (defun* (+ -> real) (&rest (numbers real))
;;; (apply #’cl:+ numbers))
;;;
;;; ;; More complicated lambda list.
;;; ;; Note that the function and its first argument do not have type
;;; ;; declarations.
;;; ;; Also note the syntax of typed keyword arguments:
;;; ;; ((var TYPE [ASSERTION]) DEFAULT [SUPPLIEDP])
;;; ;; Note that &OPTIONAL arguments use the same syntax.
;;; (defun* my-find (item (seq sequence) &key (from-end boolean)
;;; ((test (or null (function (t)))) nil)
;;; ((test-not (or null (function (t)))) nil)
;;; ((key (or null (function (t)))) nil)
;;; (start fixnum) (end fixnum))
;;; ...function body...)
;;;
;;; ;; Example of method definition. All the arguments in the arglist are
;;; ;; normal ’specialised’ arguments like you would usually find in a
;;; ;; method definition. The form still allows you to include an assertion ;;; ;; with each argument, however (’plusp’ in this case).
;;; (defmethod* (cell-value -> real) :around ((sheet <Sheet>)
;;; (x integer plusp) (y integer plusp)) ;;; ...)
;;;
;;; ;; Note that when you declare a return type for a method, the method
;;; ;; body will perform type-checking, but no toplevel DECLAIM form will
;;; ;; be generated.
;;;
;;; ;; CLOS function dispatch based on classes is limited; you cannot specialise ;;; ;; on user-defined types unless they are proper classes, for example.
;;; ;; You may therefore sometimes want to declare that a method’s argument ;;; ;; is of a particular type, as well as declaring its class for specialisation ;;; ;; as you normally would.
;;; ;; Here is an example. Note the similarity to the syntax for keyword
;;; ;; arguments.
;;; (defmethod* (cell-value -> real) :around ((sheet <Sheet>)
;;; ((x natural plusp) integer)
;;; ((y natural plusp) integer))
;;; ...)
;;;
;;; ;; Example of DEFGENERIC*, mainly useful to declare the return type
;;; ;; of a set of methods. Note the documentation string can appear after
;;; ;; the argument list, similar to DEFUN.
;;; (defgeneric* (cell-value -> real) (sheet x y)
;;; "Return the value of the cell at coordinates X,Y in SHEET.")
;;;
;;; ;; DEFGENERIC* can also be used to declare types of arguments. Be careful ;;; ;; that these don’t clash with specialisers in method definitions.
;;; (defgeneric* (cell-value -> real) (sheet (x natural) (y natural)))

* Examples of DEFVAR* and DEFPARAMETER* usage

;;; (defvar* (*user-name* string) "Bob")
;;; (defparameter* (*file-position* (integer 0)) 0)

* Type DECLARATION versus type CHECKING

Technically, =DECLARE=, =DECLAIM= and the like do not actually check that values stored in the associated variables conform to the declared type.
They merely constitute a promise /by the programmer/ that only values of
the specified type will be stored there. The consequences of storing
a string in a variable that is declared to be of type integer, are
technically ’undefined’.

In practice, most modern Common Lisp implementations perform type-checking based on declaration information, especially when the =SAFETY= setting is high.

DEFSTAR allows you to force lisp to perform type checking based on declarations. If you set the global variable [[*check-argument-types-explicitly?*]] to non-nil, =CHECK-TYPE= forms will included in the body of each function or method, causing an error to be raised if a value does not match its declared type.

* Limitations

- Definitions of =SETF= methods cannot include return type declarations in the method ’header’. The return type can still be declared using a =(:RETURNS ...)= form. For example:
;;; (defmethod (setf (foo -> integer)) (...args...) ; illegal
;;; ...)
;;;
;;; (defmethod (setf foo) (...args...)
;;; (:returns integer) ; legal
;;; ...)

* Syntax highlighting of DEFSTAR macros in Emacs

Put the following code in your =.emacs= if you want =DEFVAR*= and other
forms to appear in the same face as their normal counterparts, and if
you want their docstrings to also be correctly identified as docstrings
rather than normal strings.

;;; ;; fontify doc strings in correct face
;;; ;; lisp-mode already fontifies ’defun*’ correctly
;;; (put ’defvar* ’doc-string-elt 3)
;;; (put ’defparameter* ’doc-string-elt 3)
;;; (put ’lambda* ’doc-string-elt 2)
;;;
;;; (defvar *lisp-special-forms*
;;; (regexp-opt ’("defvar*"
;;; "defconstant*"
;;; "defparameter*"
;;; "defgeneric*"
;;; "defmethod*"
;;; "lambda*"
;;; "flet*"
;;; "labels*") ’words))
;;; (font-lock-add-keywords ’lisp-mode
;;; ‘((,*lisp-special-forms* . font-lock-keyword-face)))

Source

defstar.lisp (file)

Use List

common-lisp

Exported Definitions
Internal Definitions

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

5 Definitions

Definitions are sorted by export status, category, package, and then by lexicographic order.


Next: , Previous: , Up: Definitions   [Contents][Index]

5.1 Exported definitions


Next: , Previous: , Up: Exported definitions   [Contents][Index]

5.1.1 Special variables

Special Variable: *check-argument-types-explicitly?*

If non-nil, insert =CHECK-TYPE= clauses in the preamble of functions, to force the function’s arguments to be explicitly type-checked.

Technically, =DECLARE, DECLAIM= and the like do not actually check that values stored in the associated variables conform to the declared type. They merely constitute a promise /by the programmer/ that only values of the specified type will be stored there. The consequences of storing a string in a variable that is declared to be of type integer, are undefined.

In practise, essentially all modern lisps do perform type checking based on declarations, especially when the =SAFETY= setting is high.

Package

defstar

Source

defstar.lisp (file)

Special Variable: *use-closer-mop?*

If set to non-nil and the CLOSER-MOP package is loaded, use its DEFMETHOD and DEFGENERIC definitions rather than those from the COMMON-LISP package.

Package

defstar

Source

defstar.lisp (file)


Previous: , Up: Exported definitions   [Contents][Index]

5.1.2 Macros

Macro: *let (&rest CLAUSES) &body BODY

* Arguments
- CLAUSES :: A series of zero or more clauses taking the form:
: clause = VARNAME
: | (VARNAME FORM)
: | (LAMBDA-LIST FORM)
: | ((:values VAR...) FORM)
: | (VARNAME TYPE FORM)
- BODY :: The body of the form (implicit =progn=).
* Description
Behaves like LET*, but:
- When types are given between the variable name and expression, these are converted to declarations within the scope of the LET form.
- When the form to be bound is a list or cons cell, behaves like DESTRUCTURING-BIND.
- When the form to be bound is a list whose first element is :values, behaves like MULTIPLE-VALUE-BIND, using the rest of the elements in the form as the variables to be bound. Those elements may be symbols, or lists of the form (SYMBOL TYPE), in which case the bound symbol will be declared to be of the given type.
- Any variables whose names are ’_’, either bare or inside a form to be destructured, will be renamed with unique symbols and declared ’ignored’ within the body. This provides a quick way to ignore arguments or parts of arguments.
* Example
;;; (*let ((name "Bob")
;;; (age integer 40)
;;; (sex (member :male :female) :male)
;;; ((num street &optional suburb) address)
;;; ((:values (day fixnum) month year) birthday))
;;; ...body...)
Expands to:
;;; (let ((name "Bob"))
;;; (let ((age 40))
;;; (declare (integer age))
;;; (let ((sex :male))
;;; (declare ((member :male :female) sex))
;;; (destructuring-bind
;;; (num street &optional suburb) address
;;; (multiple-value-bind (day month year) birthday
;;; (declare (fixnum day))
;;; ...body...)))))

Package

defstar

Source

defstar.lisp (file)

Macro: defgeneric* FNAME GENERIC-ARGLIST &body OPTIONS

* Arguments
- FNAME :: Name of the generic function. Handles names of the form (SETF X) correctly.
- GENERIC-ARGLIST :: Follows the same grammar the arglist for [[defun*]] forms, except that =&REST, &KEY= and =&OPTIONAL= arguments must be of the form:
: arg = VARNAME
: | (VARNAME TYPE)
- OPTIONS :: Options to DEFGENERIC. Any of these may be simple strings, which will be concatenated together and the resulting string treated as equivalent to =(:documentation STRING)=.
One extra option is allowed – (:layered BOOL). If this is present and BOOL is a non-nil constant, the form will generate a ContextL ‘define-layered-function’ rather than ‘defgeneric’.

* Description
Usage is exactly the same as [[defun*]], except that value-checking assertions are ignored.

If you define any methods inside the form using ‘:method’ clauses, they can use [[defmethod*]]-style argument lists, :pre and :post clauses, and so on.

Note that you can declare types for arguments in the generic function argument list. Be careful that these do not clash with method definitions. Type declarations for generic function arguments will only be used to
make a toplevel =DECLAIM= form that will then apply to all methods of
the generic function.

* Examples:
;;; (defgeneric* (length -> integer) (seq &key start)
;;; "Return the length of the sequence SEQ."
;;; ...options...)
;;;
;;; (defgeneric* (length -> integer) ((seq sequence) &key (start integer)) ;;; ...options...)

Package

defstar

Source

defstar.lisp (file)

Macro: defmethod* FNAME METHOD-ARGLIST &body BODY

* Arguments

Usage is exactly the same as [[defun*]], except that within =METHOD-ARGLIST=, any list in a non-optional position (prior to any =&key, &rest,= or =&optional= keyword) is assumed to be a specialised lambda list term of the form =(VARNAME CLASS [assertion])=, rather than a DEFUN* type-declaring term.

The syntax of METHOD-ARGLIST is therefore:
: arglist-and-qualifiers = [qualifier]* method-arglist
: qualifier = :in-layer LAYER
: | :in LAYER
: | :around
: | :before
: | :after (etc)
: method-arglist = method-term*
: | (method-term* [&optional opt-term+])
: | (method-term* [&key opt-term+])
: | (method-term* [&rest rest-term])
: method-term = VARNAME
: | (VARNAME CLASS [assertion])
: | ((VARNAME TYPE/CLASS [assertion]) CLASS)
The rest of the syntax is the same as for DEFUN*.

If the :in or :in-layer qualifier is present (they are synonymous), this form will generate a ContextL ‘define-layered-method’ form rather than a ‘defmethod’.

* Description
Equivalent to =(DEFMETHOD FNAME METHOD-ARGLIST . body)= with type declarations and assertions as per [[defun*]].

* Examples
;;; (deftype positive-integer () ‘(integer 1))
;;;
;;; (defmethod (make-coords -> (cons positive-integer positive-integer)) ;;; (((x positive-integer) integer)
;;; ((y positive-integer) integer))
;;; (cons x y))

Package

defstar

Source

defstar.lisp (file)

Macro: defparameter* VAR VALUE &optional DOCSTRING

* Description
Like [[defvar*]], but expands to =DEFPARAMETER= rather than =DEFVAR=. See [[defvar*]] for more details.

Package

defstar

Source

defstar.lisp (file)

Macro: defun* FNAME ARGLIST &body BODY

* Arguments
- FNAME :: either the name of the function to be created, or a list with the following grammar:
: fname = FUNCTION-NAME
: | (FUNCTION-NAME -> TYPE [assertion])
: assertion = FORM
: | PREDICATE-SYMBOL
Where:
- =TYPE= is any valid type specifier
- =FORM= is any form, which must return non-nil if the assertion is satisfied, nil otherwise. Within the form, the symbol =RESULT= is bound to the
value that is about to be returned by the function.
- =PREDICATE-SYMBOL= is a symbol, the name of a function that accepts a single argument. Equivalent to the form =(PREDICATE-SYMBOL RESULT)=.

/Note:/ if the latter (list) form for fname is used, the =DEFUN*= body may /not/ also contain a =:returns= form. Also note that the latter form cannot currently be used when defining a =(setf ...)= function or method.
- ARGLIST :: a =DEFUN*= LAMBDA LIST, which uses the following grammar:
: arglist = var-term*
: | (var-term* [&optional opt-term+])
: | (var-term* [&key opt-term+])
: | (var-term* [&rest rest-term])
: var-term = VARNAME
: | (VARNAME TYPE/CLASS [assertion])
: rest-term = VARNAME
: | (VARNAME ELEMENT-TYPE)
: opt-term = VARNAME
: | (var-term DEFAULT [SUPPLIEDP])
Where:
- =VARNAME= is a symbol that will name the variable bound to the function argument.
- =TYPE/CLASS= and =ELEMENT-TYPE= are forms that are legal type declarations. For example, the name of a simple type or class, or a list if the type declaration is more complex.
- =DEFAULT= and =SUPPLIED-P= are the default value, and a variable that will indicate whether the argument was supplied.
- BODY :: Body of the function form. This may contain a docstring in the usual place, and may also contain:
- a single special form beginning with =:returns=:
: returns-form = (:RETURNS TYPE [assertion])
If the =:returns= form contains an assertion, then within that assertion, the symbol =RESULT= is bound to the value that the function is
about to return.
- a single special form beginning with =:pre= followed by one or more expressions, which will be evaluated before any other code in the body. All of the expressions must evaluate to non-nil, or an error is signalled. : pre-form = (:PRE [assertion] [assertion]*)
- a single special form beginning with =:post= followed by one or more expressions, which will be evaluated just prior to the function returning. All of the expressions must evaluate to non-nil, or an error is signalled. Within the :post clause, =result= is bound to the return value of the function.
: post-form = (:POST [assertion] [assertion]*)

* Description
Equivalent to =(DEFUN fname arglist . body)=, but:
- All type declarations within the lambda list will be turned into =(DECLARE...)= forms within the function body
- If a return type is declared for the function itself, this will be turned into a global =DECLAIM= form that immediately precedes the function.
- Any variables whose names are ’_’ are renamed with unique symbols
and declared ’ignored’ within the function body. This provides a quick way to ignore arguments or parts of arguments.
- All assertions within the lambda list or =:pre= form will be checked before the function body is entered.
- Any assertions within a =:returns= form or =:post= form will be checked before the function returns a value.

* Examples
;;; ;; Very simple example
;;; (defun* (add -> real) ((a real) (b real))
;;; (+ a b))

;;; ;; Example with assertion for ’b’ argument, checked before the
;;; ;; body of the function is entered.
;;; (defun* div ((a real) (b real (/= b 0)))
;;; (:returns real)
;;; (/ a b))

;;; ;; Similar to above example but using :pre clause.
;;; (defun* div ((a real) (b real))
;;; (:returns real)
;;; (:pre (/= b 0))
;;; (/ a b))

;;; (defun* sum (&rest (nums real)) ; type of ’rest’ var refers to
;;; (:returns real) ; the type of each list element, ie
;;; (apply #’+ nums)) ; nums must be a list of REALs

;;; (defun* (sum -> real) (&rest (nums real)) ; alternative form
;;; (apply #’+ nums)) ; for above example

;;; ;; This function and first argument have no type declarations.
;;; ;; Keyword argument ’test’ accepts a function that takes
;;; ;; two arguments of any type.
;;; (defun* find-in-tree (item (tree cons)
;;; &key ((test (function (t t))) #’equal))
;;; (or (funcall test item tree)
;;; (and (consp tree)
;;; (or (find-in-tree item (car tree))
;;; (find-in-tree item (cdr tree))))))

Package

defstar

Source

defstar.lisp (file)

Macro: defvar* VAR VALUE &optional DOCSTRING

* Arguments
- VAR :: either:
1. A variable name: in this case =DEFVAR*= has exactly the same effect as =DEFVAR=.
2. =(VARNAME TYPE)= where =VARNAME= is a variable name and =TYPE= is a type declaration.
- VALUE :: A form which is evaluated when the variable is first created. - DOCSTRING :: Documentation string.

* Returns
The name of the variable as a symbol.

* Description
Creates the global special variable =VAR=, initialises it to =VALUE=,
and declares it to be of type =TYPE=, if given.

* Examples
;;; (defvar* (*file-name* string) "~/log.txt")

Package

defstar

Source

defstar.lisp (file)

Macro: flet* CLAUSES &body BODY

* Arguments
- CLAUSES :: List of clauses. Takes the following grammar:
: clauses = clause*
: clause = (FNAME ARGLIST ...body...)
See [[defun*]] for a description of the grammar of =FNAME= and =ARGLIST=. - BODY :: Body of the form.

* Description
Like =FLET=, but within each function-definition clause the function name, arglist and body have the same syntax as for [[defun*]].

* Examples
;;; (defun foo (name x y)
;;; (flet* (((area -> integer) ((x integer) (y integer))
;;; (* x y)))
;;; (format t "Area of ~A is ~D.~%" name (area x y))))

Package

defstar

Source

defstar.lisp (file)

Macro: labels* CLAUSES &body BODY

* Arguments
See [[flet*]].

* Description
Like =LABELS=, but within each clause the function name, arglist and body have the same syntax as for [[defun*]].

See [[flet*]] for more details.

Package

defstar

Source

defstar.lisp (file)

Macro: lambda* ARGLIST &body BODY

* Description
Like =LAMBDA=, but =ARGLIST= and body have the same syntax as for [[defun*]]. A =:returns= form can be used within the function body to
declare its return type.

Package

defstar

Source

defstar.lisp (file)

Macro: nlet NAME (&rest BINDINGS) &body BODY

Identical to *LET, but recursion can occur by calling (NAME ARGS...)
within BODY, where each argument in ARGS matches one binding.
The same as Scheme’s named LET. Note that the macro does NOT perform tail call optimisation. (All modern lisp compilers will perform TCO of the generated code however.)
* Example
;;; (nlet fact ((n 5))
;;; (if (= 1 n)
;;; n
;;; (* n (fact (1- n)))))

Package

defstar

Source

defstar.lisp (file)


Previous: , Up: Definitions   [Contents][Index]

5.2 Internal definitions


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.1 Constants

Constant: +defun*-arrow-symbol+

The symbol that separates function name from type declaration in =DEFUN*= forms and the like. See [[defun*]].

Package

defstar

Source

defstar.lisp (file)


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.2 Special variables

Special Variable: *use-contextl*

Bound to true if the ContextL package is currently loaded.

Package

defstar

Source

defstar.lisp (file)


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.3 Macros

Macro: defvar/param TOPLEVEL-FORM-NAME VAR VALUE &optional DOCSTRING

* Arguments
- TOPLEVEL-FORM-NAME :: Symbol denoting the type of toplevel form being defined. For example, =’DEFUN=.
- VAR :: Symbol or list.
- VALUE :: Form that will be evaluated to initialise the variable being defined.
- DOCSTRING :: String used as documentation.
* Return Value
A symbol.
* Description
Internal macro, used by [[defvar*]] and
[[defparameter*]].

Package

defstar

Source

defstar.lisp (file)


Previous: , Up: Internal definitions   [Contents][Index]

5.2.4 Functions

Function: assert-postcondition FNAME CLAUSE VARNAMES
Package

defstar

Source

defstar.lisp (file)

Function: assert-precondition FNAME CLAUSE VARNAMES
Package

defstar

Source

defstar.lisp (file)

Function: defstar/ampersand-symbol? SYM

* Arguments
- SYM :: A symbol.
* Return Value
Boolean.
* Description
Predicate. Does the symbol =SYM= begin with an ampersand, such as =&ANY=, =&REST= and so on?

Package

defstar

Source

defstar.lisp (file)

Function: defstar/make-keyword &rest PARTS

* Arguments
- PART :: Any lisp value; usually a string or symbol.

* Return Value
A keyword.

* Description
Concatenates the printed representations of =PARTs= together into a single string, then makes a symbol from that string, and interns the symbol in the =KEYWORD= package. Returns the new keyword.

* See Also
[[mksymbol]]

Package

defstar

Source

defstar.lisp (file)

Function: defstar/split-defun-body BODY &optional FORCE-DOCSTRING?

* Arguments
- BODY :: the body of a =DEFUN= form or similar, such as might be received by a macro.
- FORCE-DOCSTRING? :: if true, and the body is a list whose only element is a string, that string will still be interpreted as a docstring rather than a constant return value for the body.

* Returns
Three values:
- PREAMBLE :: list of declaration forms at the start of the body
- DOCSTRING :: Documentation string, if present in =BODY=.
- TRUE-BODY :: Actual function body with the above items removed.

* Description
Internal utility function.
Divide the ’preamble’ of a function body from its actual body.
The preamble consists of declarations and a docstring.

Package

defstar

Source

defstar.lisp (file)

Function: defstar/varnames-in-arglist ARGLIST
Package

defstar

Source

defstar.lisp (file)

Function: defun*-term TERM LAST-AMP-KWD &key DEF-TYPE

* Arguments
- TERM :: any member of an ordinary lambda list.
- LAST-AMP-KWD :: Symbol or nil.
- DEF-TYPE :: Symbol denoting the type of toplevel form that is being created. The default is =’DEFUN=.
* Returns
Four values:
1. The term as it should be included in the final argument list for
the toplevel form (symbol or list)
2. The declaration clause that should be included in the
=DECLARE= statement within the toplevel form’s body
3. The type of the term, for inclusion in the argument-list of
the =(DECLAIM (FTYPE (FUNCTION arglist RETURN-TYPE) ...))= form for a function definition.
4. The assertion clause.

* Description
Internal function, used by [[defun*]] to parse lambda list terms.

* See Also
- [[defun*]]

Package

defstar

Source

defstar.lisp (file)

Function: ignored-in-preamble? VARNAME PREAMBLE
Package

defstar

Source

defstar.lisp (file)

Function: ignored-variable? VAR
Package

defstar

Source

defstar.lisp (file)

Function: map-tree FN TREE

Like MAPCAR but operates on a tree. FN must take one argument. It is called for every atom in TREE; a structural copy of TREE is returned in which every atom is replaced by the value of (FN ATOM).

Package

defstar

Source

defstar.lisp (file)

Function: named-*let-aux NAME CLAUSES BODY
Package

defstar

Source

defstar.lisp (file)

Function: safe-define TOPLEVEL-FORM-NAME FNAME ARGLIST BODY &key GENERIC-FUNCTION-NAME

* Arguments
- TOPLEVEL-FORM-NAME :: Symbol denoting the type of toplevel form being defined. Currently handles =’DEFUN, ’DEFMETHOD, ’FLET, ’LABELS, ’LAMBDA, ’DEFGENERIC=. - FNAME, ARGLIST, BODY :: see [[defun*]].
- GENERIC-FUNCTION-NAME :: supplied for methods defined via a ‘:method’ clause inside a ‘defgeneric*’ form. A symbol naming the generic function to which the methods belong.

* Returns
A =defun, defmethod, defgeneric= or =lambda= form, or =flet= or
=labels= subclause, containing appropriate declarations.

* Description
Internal function. The workhorse for the macros [[DEFUN*]], [[DEFMETHOD*]], [[LAMBDA*]], [[FLET*]], and [[LABELS*]].

Package

defstar

Source

defstar.lisp (file)


Previous: , Up: Top   [Contents][Index]

Appendix A Indexes


Next: , Previous: , Up: Indexes   [Contents][Index]

A.1 Concepts

Jump to:   D   F   L  
Index Entry  Section

D
defstar.asd: The defstar<dot>asd file
defstar/defstar.lisp: The defstar/defstar<dot>lisp file

F
File, Lisp, defstar.asd: The defstar<dot>asd file
File, Lisp, defstar/defstar.lisp: The defstar/defstar<dot>lisp file

L
Lisp File, defstar.asd: The defstar<dot>asd file
Lisp File, defstar/defstar.lisp: The defstar/defstar<dot>lisp file

Jump to:   D   F   L  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.2 Functions

Jump to:   *  
A   D   F   I   L   M   N   S  
Index Entry  Section

*
*let: Exported macros

A
assert-postcondition: Internal functions
assert-precondition: Internal functions

D
defgeneric*: Exported macros
defmethod*: Exported macros
defparameter*: Exported macros
defstar/ampersand-symbol?: Internal functions
defstar/make-keyword: Internal functions
defstar/split-defun-body: Internal functions
defstar/varnames-in-arglist: Internal functions
defun*: Exported macros
defun*-term: Internal functions
defvar*: Exported macros
defvar/param: Internal macros

F
flet*: Exported macros
Function, assert-postcondition: Internal functions
Function, assert-precondition: Internal functions
Function, defstar/ampersand-symbol?: Internal functions
Function, defstar/make-keyword: Internal functions
Function, defstar/split-defun-body: Internal functions
Function, defstar/varnames-in-arglist: Internal functions
Function, defun*-term: Internal functions
Function, ignored-in-preamble?: Internal functions
Function, ignored-variable?: Internal functions
Function, map-tree: Internal functions
Function, named-*let-aux: Internal functions
Function, safe-define: Internal functions

I
ignored-in-preamble?: Internal functions
ignored-variable?: Internal functions

L
labels*: Exported macros
lambda*: Exported macros

M
Macro, *let: Exported macros
Macro, defgeneric*: Exported macros
Macro, defmethod*: Exported macros
Macro, defparameter*: Exported macros
Macro, defun*: Exported macros
Macro, defvar*: Exported macros
Macro, defvar/param: Internal macros
Macro, flet*: Exported macros
Macro, labels*: Exported macros
Macro, lambda*: Exported macros
Macro, nlet: Exported macros
map-tree: Internal functions

N
named-*let-aux: Internal functions
nlet: Exported macros

S
safe-define: Internal functions

Jump to:   *  
A   D   F   I   L   M   N   S  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.3 Variables

Jump to:   *   +  
C   S  
Index Entry  Section

*
*check-argument-types-explicitly?*: Exported special variables
*use-closer-mop?*: Exported special variables
*use-contextl*: Internal special variables

+
+defun*-arrow-symbol+: Internal constants

C
Constant, +defun*-arrow-symbol+: Internal constants

S
Special Variable, *check-argument-types-explicitly?*: Exported special variables
Special Variable, *use-closer-mop?*: Exported special variables
Special Variable, *use-contextl*: Internal special variables

Jump to:   *   +  
C   S  

Previous: , Up: Indexes   [Contents][Index]

A.4 Data types

Jump to:   D   P   S  
Index Entry  Section

D
defstar: The defstar system
defstar: The defstar package
defstar-system: The defstar-system package

P
Package, defstar: The defstar package
Package, defstar-system: The defstar-system package

S
System, defstar: The defstar system

Jump to:   D   P   S