reduce-operator declaration is provided to inform the
compiler that certain names are n-ary versions of binary operators.
Here are some examples:
(declare (reduce-operator (cons* cons)))
(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
(declare (reduce-operator (list cons (null-value '() any))))
(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) ==> '()
(declare (reduce-operator (- %- (null-value 0 single) (group left))))
(- x y z w) ==> (%- (%- (%- x y) z) w) (- x y) ==> (%- x y) (- x) ==> (%- 0 x) (-) ==> 0
(declare (reduce-operator (+ %+ (null-value 0 none) (group right))))
(+ 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
+ by replacing them with calls to
%+. You should
provide a definition of
%+ as well, although it is not required.
(declare (reduce-operator (apply (primitive cons) (group right) (wrapper (global apply) 1))))
(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)] ))
- n and m are non-negative integers.
- name is a symbol.
- binop, value, unop, and wrap are simple expressions in one of these forms:
- A constant.
- A variable.
- The primitive procedure named primitive-name. The optional element arity specifies the number of arguments that the primitive accepts.
- A global variable.
- null-option is either
- ordering is either
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.
groupoption specifies whether name associates to the right or left.
null-valueoption specifies a value to use in the following cases:
- When no arguments are supplied to name, value is returned.
- When a single argument is provided to name, value becomes the second argument to binop.
- 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.
singletonoption specifies a function, unop, to be invoked on the single argument given. This option supersedes the
null-valueoption, which can only take the value
wrapperoption 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.