# Differences

This shows you the differences between two versions of the page.

 cl:functions:reduce [2019/09/14 05:00] cl:functions:reduce [2019/09/22 06:00] (current) Line 1: Line 1: + ====== Function REDUCE ====== + + ====Syntax==== + * **reduce** //​function//​ //​sequence//​ ''&​key''​ //key// //​from-end//​ //start// //end// //​initial-value//​ → //result// + + ====Arguments and Values==== + //​function//​ - a //​[[CL:​Glossary:​designator]]//​ for a //​[[CL:​Glossary:​function]]//​ that might be called with either zero or two //​[[CL:​Glossary:​argument|arguments]]//​. + //​sequence//​ - a //​[[CL:​Glossary:​proper sequence]]//​. + //key// - a //​[[CL:​Glossary:​designator]]//​ for a //​[[CL:​Glossary:​function]]//​ of one argument, or **[[CL:​Constant Variables:​nil]]**. + //​from-end//​ - a //​[[CL:​Glossary:​generalized boolean]]//​. The default is //​[[CL:​Glossary:​false]]//​. + //start//, //end// - //​[[CL:​Glossary:​bounding index designator|bounding index designators]]//​ of //​sequence//​. The defaults for //start// and //end// are ''​0''​ and **[[CL:​Constant Variables:​nil]]**,​ respectively. + //​initial-value//​ - an //​[[CL:​Glossary:​object]]//​. + //result// - an //​[[CL:​Glossary:​object]]//​. + + ====Description==== + **reduce** uses a binary operation, //​function//,​ to combine the //​[[CL:​Glossary:​element|elements]]//​ of //​sequence//​ //​[[CL:​Glossary:​bounded]]//​ by //start// and //end//. + + The //​function//​ must accept as //​[[CL:​Glossary:​argument|arguments]]//​ two //​[[CL:​Glossary:​element|elements]]//​ of //​sequence//​ or the results from combining those //​[[CL:​Glossary:​element|elements]]//​. The //​function//​ must also be able to accept no arguments. + + If //key// is supplied, it is used is used to extract the values to reduce. The //key// function is applied exactly once to each element of //​sequence//​ in the order implied by the reduction order but not to the value of //​initial-value//,​ if supplied. + + The //key// function typically returns part of the //​[[CL:​Glossary:​element]]//​ of //​sequence//​. If //key// is not supplied or is **[[CL:​Constant Variables:​nil]]**,​ the //​sequence//​ //​[[CL:​Glossary:​element]]//​ itself is used. + + The reduction is left-associative,​ unless //​from-end//​ is //​[[CL:​Glossary:​true]]//​ in which case it is right-associative. + + If //​initial-value//​ is supplied, it is logically placed before the subsequence (or after it if //​from-end//​ is //​[[CL:​Glossary:​true]]//​) and included in the reduction operation. + + In the normal case, the result of **reduce** is the combined result of //​function//'​s being applied to successive pairs of //​[[CL:​Glossary:​element|elements]]//​ of //​sequence//​. + + If the subsequence contains exactly one //​[[CL:​Glossary:​element]]//​ and no //​initial-value//​ is given, then that //​[[CL:​Glossary:​element]]//​ is returned and //​function//​ is not called. If the subsequence is empty and an //​initial-value//​ is given, then the //​initial-value//​ is returned and //​function//​ is not called. + + If the subsequence is empty and no //​initial-value//​ is given, then the //​function//​ is called with zero arguments, and **reduce** returns whatever //​function//​ does. This is the only case where the //​function//​ is called with other than two arguments. + + ====Examples==== + <​blockquote> ​ + (reduce #'​[[CL:​Functions:​math-multiply|*]] '(1 2 3 4 5)) <​r>​120 + (reduce #'​[[CL:​Functions:​append]] '((1) (2)) :​initial-value '(i n i t)) (I N I T 1 2) + (reduce #'​[[CL:​Functions:​append]] '((1) (2)) :from-end t :​initial-value '(i n i t)) (1 2 I N I T) + (reduce #'​[[CL:​Functions:​math-subtract|-]] '(1 2 3 4)) + ≡ ([[CL:​Functions:​math-subtract|-]] ([[CL:​Functions:​math-subtract|-]] ([[CL:​Functions:​math-subtract|-]] 1 2) 3) 4) -8 + (reduce #'​[[CL:​Functions:​math-subtract|-]] '(1 2 3 4) :from-end [[CL:​Constant Variables:​t]]) ;​Alternating sum. + ≡ ([[CL:​Functions:​math-subtract|-]] 1 ([[CL:​Functions:​math-subtract|-]] 2 ([[CL:​Functions:​math-subtract|-]] 3 4))) -2 + (reduce #'​[[CL:​Functions:​math-add|+]] '()) 0 + (reduce #'​[[CL:​Functions:​math-add|+]] '(3)) 3 + (reduce #'​[[CL:​Functions:​math-add|+]] '​(foo)) <​r>​FOO + (reduce #'​[[CL:​Functions:​list]] '(1 2 3 4)) <​r>​(((1 2) 3) 4) + (reduce #'​[[CL:​Functions:​list]] '(1 2 3 4) :from-end [[CL:​Constant Variables:​t]]) (1 (2 (3 4))) + (reduce #'​[[CL:​Functions:​list]] '(1 2 3 4) :​initial-value 'foo) <​r>​((((foo 1) 2) 3) 4) + (reduce #'​[[CL:​Functions:​list]] '(1 2 3 4) :from-end [[CL:​Constant Variables:​t]] :​initial-value 'foo) (1 (2 (3 (4 foo)))) + ​ + + ====Side Effects==== + None. + + ====Affected By==== + None. + + ====Exceptional Situations==== + Should be prepared to signal an error of type type-error if //​sequence//​ is not a //​[[CL:​Glossary:​proper sequence]]//​. + + ====See Also==== + * {\secref\TraversalRules} + + ====Notes==== + None. + + \issue{MAPPING-DESTRUCTIVE-INTERACTION:​EXPLICITLY-VAGUE} \issue{REDUCE-ARGUMENT-EXTRACTION} \issue{SUBSEQ-OUT-OF-BOUNDS} \issue{RANGE-OF-START-AND-END-PARAMETERS:​INTEGER-AND-INTEGER-NIL} \issue{REDUCE-ARGUMENT-EXTRACTION}

### Page Tools 