Reduction of Operators - MIT/GNU Scheme 7.7.91
Description: MIT/GNU Scheme 7.7.91

Previous: Replacement of Operators, Up: Declarations

#### 4.2.4 Operator Reduction

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 (cons x (cons y (cons z w))))
         (apply f x y)
            ==> ((access apply ()) f (cons x y))
         (apply f x) ==> (apply f x)
         (apply f) ==> (apply f)
         (apply) ==> (apply)

— declaration+: reduce-operator name ...

> 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`, or `empty`.
> - ordering is either `left`, `right`, or `associative`.

> 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 the `null-value` option, which can only take the value `none`.
> - 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.