Documentation for routine produce

Documentation for routine produce, assembled from the following types:

class Any

From Any

(Any) method produce

Defined As:

method produce(--> Nil)

TODO

class List

From List

(List) routine produce

Defined as:

multi sub    produce(&with*@values)
multi method produce(List:D: &with)

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 meta-operator [\ ] provides a syntactic shortcut for producing with an infix operator:

# The following all do the same thing... 
my @numbers = (1,2,3,4,5);
say produce { $^a + $^b }@numbers;
say produce * + *@numbers;
say produce &[+], @numbers# operator does not need explicit identity 
say [\+@numbers;          # 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: { last if $^a > 7$^a + $^b }# OUTPUT: «(2 5 9)␤» 

class Supply

From Supply

(Supply) method produce

method produce(Supply:D: &with --> Supply:D)

Creates a "producing" supply with the same semantics as List.produce.

my $supply = Supply.from-list(1..5).produce({$^a + $^b});
$supply.tap(-> $v { say "$v" }); # OUTPUT: «1␤3␤6␤10␤15␤»