The Repeat modifier

Repeat (⍟) is a 2-modifier that applies its operand function 𝔽 multiple times.

↗️
    »»» "ABCDE"
"   AB"

    »⍟3 "ABCDE"
"   AB"

In mathematics (which unsurpisingly tends to use complicated terms to talk about an easy concept), this kind of repetition is called an iterated function and written with exponential notation. It's related to function composition ∘ in the same way that exponentiation (⋆) relates to multiplication (Γ—): function iteration is repeated composition.

n⋆4  ←→  nΓ—nΓ—nΓ—n
F⍟4  ←→  F∘F∘F∘F

F⍟0 repeats F zero times, that is, does nothing. Like n⋆0 gives the multiplicative identity 1, F⍟0 is the compositional identity, ⊒. Since F⍟1 applies F and F⍟0 doesn't, Repeat might be pronounced "if" or "conditional" when 𝔾 is boolean.

BQN's Repeat modifier has some extra functionality relative to the mathematical version. It allows a left argument, and some extensions to the right operand 𝔾. As usual for 2-modifiers, 𝔾 is actually a function that applies to the arguments to give a result. The result can be a natural number as shown above, or a negative number to Undo (⁼) 𝔽, or an array of values.

Left argument

If 𝕨 is given, it's passed as the left argument to 𝔽 for every invocation.

↗️
    3 +⍟2 7
13
    3 + 3 + 7
13

This kind of composition can't be represented by ∘ anymore (you'd need a train), but it's similar in spirit. 𝕨 π”½βŸn 𝕩 is always equivalent to π•¨βŠΈπ”½βŸn 𝕩, provided n is a constantβ€”not a function, as discussed in the next section.

Dynamic repetition count

In the general case, 𝔾 is a function, which is applied to all arguments to get the repetition count. That is, the actual count is 𝕨𝔾𝕩.

↗️
    ∾⟜1⍟⊒ 4
⟨ 4 1 1 1 1 ⟩

    1⊸+βŸβ‰  ↕4
⟨ 4 5 6 7 ⟩

The most common use is the case where 𝔾 is a condition that returns 0 or 1. Then Repeat simply applies 𝔽 if the condition holds. For example, the following code halves numbers that are greater than 6.

↗️
    ÷⟜2⍟{6<𝕩}Β¨ 3β€Ώ7β€Ώ2β€Ώ1β€Ώ8
⟨ 3 3.5 2 1 4 ⟩

If 𝕨 is given, then 𝔾 gets it as a left argument (to avoid this, use π•¨βŠΈπ”½βŸπ”Ύ 𝕩, which applies 𝔾 to 𝕩 only). This form also works well with a boolean condition.

↗️
    3 ⊣⍟<Β¨ 2β€Ώ4β€Ώ6  # Left if less, i.e. minimum
⟨ 2 3 3 ⟩

Negative repetition

What does it mean to repeat a function a negative number of times? For a negative integer -n, BQN defines F⍟(-n) to be F⁼⍟n. In particular, F⍟¯1 simply undoes F.

↗️
    1 ⌽⍟¯1 "abcde"  # Rotate backwards
"eabcd"

Because BQN's Undo is a little looser than a strict mathematical inverse, this is an extension of the function inverse written f⁻¹ in mathematics. As a result, it doesn't have all the same properties. For natural numbers, Repeat follows the rule that F⍟m F⍟n 𝕩 is F⍟(m+n) 𝕩. For integers, we have 𝕩 ≑ F⍟n F⍟(-n) 𝕩, but not necessarily 𝕩 ≑ F⍟(-n) F⍟n 𝕩.

Array of repetition counts

The value of 𝕨𝔾𝕩 might also be an array, whose elements are any valid repetition valuesβ€”integers, or other arrays. Each integer in the nested structure is replaced with the result of repeating 𝔽 that many times.

↗️
    2βŠΈΓ—βŸβŸ¨2,⟨4,Β―2,1⟩⟩ 1
⟨ 4 ⟨ 16 0.25 2 ⟩ ⟩

Regardless of how numbers in 𝕨𝔾𝕩 are arranged, 𝔽 is evaluated the minimum number of times required to find the result, and regular (positive) applications are all performed before reverse (negative) ones. So the pattern of application is entirely defined by the smallest and largest values given by 𝔾.