Previous: Replacement of Operators, Up: Declarations
The reduce-operator
declaration is provided to inform the
compiler that certain names are n-ary versions of binary operators.
Here are some examples:
Declaration:
(declare (reduce-operator (cons* cons)))
Replacements:
(cons* x y z w) ==> (cons x (cons y (cons z w))), (cons* x y) ==> (cons x y) (cons* x) ==> x (cons*) error--> too few arguments
Declaration:
(declare (reduce-operator (list cons (null-value '() any))))
Replacements:
(list x y z w) ==> (cons x (cons y (cons z (cons w '())))) (list x y) ==> (cons x (cons y '())) (list x) ==> (cons x '()) (list) ==> '()
Declaration:
(declare (reduce-operator (- %- (null-value 0 single) (group left))))
Replacements:
(- x y z w) ==> (%- (%- (%- x y) z) w) (- x y) ==> (%- x y) (- x) ==> (%- 0 x) (-) ==> 0
Declaration:
(declare (reduce-operator (+ %+ (null-value 0 none) (group right))))
Replacements:
(+ x y z w) ==> (%+ x (%+ y (%+ z w))) (+ x y) ==> (%+ x y) (+ x) ==> x (+) ==> 0
Note: This declaration does not cause an appropriate definition of
%+
(in the last example) to appear in your code. It merely
informs the compiler that certain optimizations can be performed on
calls to +
by replacing them with calls to %+
. You should
provide a definition of %+
as well, although it is not required.
Declaration:
(declare (reduce-operator (apply (primitive cons) (group right) (wrapper (global apply) 1))))
Replacements:
(apply f x y z w) ==> ((access apply #f) f (cons x (cons y (cons z w)))) (apply f x y) ==> ((access apply #f) f (cons x y)) (apply f x) ==> (apply f x) (apply f) ==> (apply f) (apply) ==> (apply)
The general format of the declaration is (brackets denote optional elements):
(reduce-operator (name binop [(group ordering)] [(null-value value null-option)] [(singleton unop)] [(wrapper wrap [n])] [(maximum m)] ))where
- n and m are non-negative integers.
- name is a symbol.
- binop, value, unop, and wrap are simple expressions in one of these forms:
'
constant- A constant.
- variable
- A variable.
(primitive
primitive-name [arity])
- The primitive procedure named primitive-name. The optional element arity specifies the number of arguments that the primitive accepts.
(global
var)
- A global variable.
- null-option is either
always
,any
,one
,single
,none
, orempty
.- ordering is either
left
,right
, orassociative
.The meaning of these fields is:
- name is the name of the n-ary operation to be reduced.
- binop is the binary operation into which the n-ary operation is to be reduced.
- The
group
option specifies whether name associates to the right or left.- The
null-value
option specifies a value to use in the following cases:
none
empty
- When no arguments are supplied to name, value is returned.
one
single
- When a single argument is provided to name, value becomes the second argument to binop.
any
always
- binop is used on the “last” argument, and value provides the remaining argument to binop.
In the above options, when value is supplied to binop, it is supplied on the left if grouping to the left, otherwise it is supplied on the right.
- The
singleton
option specifies a function, unop, to be invoked on the single argument given. This option supersedes thenull-value
option, which can only take the valuenone
.- The
wrapper
option specifies a function, wrap, to be invoked on the result of the outermost call to binop after the expansion. If n is provided it must be a non-negative integer indicating a number of arguments that are transferred verbatim from the original call to the wrapper. They are passed to the left of the reduction.- The maximum option specifies that calls with more than m arguments should not be reduced.