Function Repository Resource:

# FoldRotate

Nest a list of functions around a seed, folding in a list of elements

Contributed by: Daniel Robinson
 ResourceFunction["FoldRotate"][{f1, f2, f3, …}, x, {e1, e2, e3, …}] gives f1[x, e1], then nests the remaining f2, f3, …, folding in the e2, e3, …. ResourceFunction["FoldRotate"][{f1, f2, f3, …}, {e1, e2, e3, …}] is equivalent to ResourceFunction["FoldRotate"][{f1, f2, f3, …}, e1, {e2, e3, …}].

## Details

FoldRotate is a generalisation of Fold, going from a single function in the first argument to a list of functions.
ResourceFunction["FoldRotate"][{f1, f2, , fn}, x, {e1, e2, , en}] yields fn[…f2[f1[x, e1], e2], … en].
FoldRotate[{f}, x, {e1, e2, e3, }] is equivalent to Fold[f, x, {e1, e2, e3, }].
FoldRotate[{f, f, f, …}, x, {e1, e2, e3, }] is equivalent to Fold[{f}, x, {e1, e2, e3, }], albeit slower.
In the case ResourceFunction["FoldRotate"][{f1, , fn}, x, {e1, , em}], if n<m, the functions fi will "rotate" from fn back around to f1. If n>m, only the first m functions will be used in the output.
Like Fold, ResourceFunction["FoldRotate"] can be exited with Throw ».
Unlike Fold, ResourceFunction["FoldRotate"] does not have any operator forms.

## Examples

### Basic Examples (7)

Apply three functions (f, g and h) and three elements (a, b and c) to a seed (x):

 In[1]:=
 Out[1]=

Use the 2-argument form to get the same result:

 In[2]:=
 Out[2]=

If the number of functions is less than the number of elements, the functions will "rotate" round to fill out:

 In[3]:=
 Out[3]=

If the number of functions is greater than the number of elements, some may not be used:

 In[4]:=
 Out[4]=

Using an empty list of functions will return the list of elements along with the seed:

 In[5]:=
 Out[5]=

Using an empty list of elements and no seed will return an empty list:

 In[6]:=
 Out[6]=

Adding a seed effectively prevents the second list from being registered as empty:

 In[7]:=
 Out[7]=

### Scope (5)

FoldRotate can take an arbitrary number of functions or elements:

 In[8]:=
 Out[8]=

FoldRotate can take pure functions. The first slot (#1) refers to the current value (starting with the seed); the second slot (#2) refers to the element being folded in:

 In[9]:=
 Out[9]=

Use Sow and Reap to get intermediary results (similar to how FoldList gets intermediary results for Fold):

 In[10]:=
 Out[10]=

An iterator and piecewise function can be used in place of multiple functions:

 In[11]:=
 Out[12]=
 In[13]:=
 Out[14]=

FoldRotate can be exited early with Throw. Use FoldRotate (along with Sow and Reap) to generate the nth partial sum in the series 1 + 2 × 3 + 4 × 5 + …:

 In[15]:=
 Out[15]=

Exit early when the partial sum is a multiple of 7:

 In[16]:=
 Out[16]=

### Applications (1)

Calculate alternating totals of a list:

 In[17]:=
 Out[17]=
 In[18]:=
 Out[18]=

### Properties and Relations (3)

FoldRotate can be used to mimic the behaviour of Fold:

 In[19]:=
 Out[19]=
 In[20]:=
 Out[20]=
 In[21]:=
 Out[21]=

In fact, if only one function is provided, FoldRotate (in its 3-argument form) reduces to Fold:

 In[22]:=
 Out[22]=

In order to return an unevaluated expression, Defer (or HoldForm) must be used at every level:

 In[23]:=
 Out[23]=

Evaluate the expression with a replacement rule:

 In[24]:=
 Out[24]=

FoldRotate is generally slower than Fold, especially when using large number of functions:

 In[25]:=
 Out[26]=
 In[27]:=
 Out[27]=

### Possible Issues (3)

FoldRotate takes either two or three arguments:

 In[28]:=
 Out[28]=
 In[29]:=
 Out[29]=

The first and last arguments must be lists:

 In[30]:=
 Out[30]=
 In[31]:=
 Out[31]=

Given no arguments at all, FoldRotate will not evaluate:

 In[32]:=
 Out[32]=

### Neat Examples (1)

Create a nesting of frames cycling through three colours:

 In[33]:=
 Out[34]=

Daniel Robinson

## Version History

• 1.0.0 – 16 June 2023