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


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) 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)
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.

Previous: Operator Replacement, Up: Declarations   [Contents][Index]