All Manuals > LispWorks User Guide and Reference Manual > 34 The COMPILER Package

NextPrevUpTopContentsIndex

deftransform

Macro
Summary

Defines a function that computes the expansion of a form.

Package

compiler

Signature

deftransform name transform-name lambda-list &body body => list-of-transforms

Arguments

name

A symbol naming the function to which the transform is to be applied.

transform-name

The symbol naming the transformation -- it should be unique for the function being transformed -- and provides a handle with which to redefine an existing transform.

lambda-list

This must match against the form being expanded before expansion is allowed to take place, in the sense that it must be valid to call a function with such a lambda list using the arguments supplied in the candidate-form for expansion.

body

The body of the expander function, the result of which replaces the original form (unless it evaluates to compiler::%pass%, in which case no transformation is applied).

Values

list-of-transforms

A list of the names of transforms defined for the function, including the one just added.

Description

deftransform, like defmacro, defines a function that computes the expansion of a form. Transforms are only used by the compiler and not by the interpreter. deftransform allows you to add to the optimizations performed by the compiler.

Examples
(compiler:deftransform  +  +-of-2  (x y)
 '(system::|+2| ,x ,y))
(compiler:deftransform  +  +-of-many (x &rest y)
 '(system::|+2| ,x (+ ,@y)))
 ;; now an expression like (+ a b c 4 5 7 d e f)
 ;; compiles to use the binary version
 ;; of + (inlined by default),   
 ;; rather than the full (slow) version of +
(compiler:deftransform  list  list-of-1 (x)
 '(cons ,x '()))
(compiler:deftransform  list  list-of-2 (x y)
 '(cons ,x (cons ,y '())))
 ;; save having to call list - 
 ;; cons is inlined by default
(compiler:deftransform  constant  my-trans  (x)
     (cond  ((constantp x)   x)
            ((consp x)     '(quote ,(eval x)))
            (t 'compiler::%pass%)))  ; give up if not a cons
(compile (defun three-list () (constant (list 1 2 3))))
 ;; the function three-list returns the 
 ;; same list (1 2 3)
 ;; every time it is called...

The list-of-2 example returns

(LIST-OF-2 LIST-OF-1 COMPILER::LIST-TRANSFORM)

as its result, since a similar transform already exists in the compiler, by the name compiler::list*-transform.

Notes

deftransform differs from defmacro in various ways:

The evaluation of the body can return compiler:%pass% indicating that the form is not to be expanded (in other words, the transform method has elected to give up trying to improve the code).

The compiler only calls the expander function if the arguments match the lambda list -- macros are unconditionally expanded.

There can be several deftransforms for the same symbol, each having a different name. (The compiler calls each one in turn until one succeeds. This repeats until they all pass, so that the replacement form may itself be transformed.)

If a transform takes keyword arguments the compiler preserves the correct order of evaluation.

A carelessly written deftransform may lead the compiler to transform valid Common Lisp into incorrect code -- there is no semantic checking of the transform.

See also

compile
compile-file


LispWorks User Guide and Reference Manual - 20 Sep 2017

NextPrevUpTopContentsIndex