Documentation for routine produce
assembled from the following pages:
Class: Any §
From Any
(Any) routine produce §
Defined as:
multi method produce(Any: & --> Nil)multi method produce(Any: )multi sub produce (, +list)
This is similar to reduce
, but returns a list with the accumulated values instead of a single result.
<10 5 3>.reduce( &[*] ).say ; # OUTPUT: «150» <10 5 3>.produce( &[*] ).say; # OUTPUT: «(10 50 150)»
The last element of the produced list would be the output produced by the .reduce
method.
If it's a class, it will simply return Nil.
Class: Supply §
From Supply
(Supply) method produce §
method produce(Supply: --> Supply)
Creates a "producing" supply with the same semantics as List.produce.
my = Supply.from-list(1..5).produce();.tap(-> ); # OUTPUT: «1361015»
Class: List §
From List
(List) routine produce §
Defined as:
multi sub produce(, *)multi method produce(List: )
Generates a list of all intermediate "combined" values along with the final result by iteratively applying a function which knows how to combine two values.
If @values
contains just a single element, a list containing that element is returned immediately. If it contains no elements, an exception is thrown, unless &with
is an operator with a known identity value.
If &with
is the function object of an operator, its inherent identity value and associativity is respected - in other words, (VAL1, VAL2, VAL3).produce(&[OP])
is the same as VAL1 OP VAL2 OP VAL3
even for operators which aren't left-associative:
# Raise 2 to the 81st power, because 3 to the 4th power is 81 [2,3,4].produce(&[**]).say; # OUTPUT: «(4 81 2417851639229258349412352)» say produce &[**], (2,3,4); # OUTPUT: «(4 81 2417851639229258349412352)» say [\**] (2,3,4); # OUTPUT: «(4 81 2417851639229258349412352)» # Subtract 4 from -1, because 2 minus 3 is -1 [2,3,4].produce(&[-]).say; # OUTPUT: «(2 -1 -5)» say produce &[-], (2,3,4); # OUTPUT: «(2 -1 -5)» say [\-] (2,3,4); # OUTPUT: «(2 -1 -5)»
A triangle metaoperator [\ ]
provides a syntactic shortcut for producing with an infix operator:
# The following all do the same thing... my = (1,2,3,4,5);say produce , ;say produce * + *, ;say produce &[+], ; # operator does not need explicit identity say [\+] ; # most people write it this way
The visual picture of a triangle [\
is not accidental. To produce a triangular list of lists, you can use a "triangular comma":
[\,] 1..5;# ( # (1) # (1 2) # (1 2 3) # (1 2 3 4) # (1 2 3 4 5) # )
Since produce
is an implicit loop, it responds to next
, last
and redo
statements inside &with
:
say (2,3,4,5).produce: ; # OUTPUT: «(2 5 9)»