Tutorials/A-Practical-Guide | Streams-Patterns-Events > A-Practical-Guide

Pattern Guide 06e: Language Control

Patterns that mimic some language-side control structures

Language control methods

Some patterns mimic language-style control methods: conditionals ( Pif ), loops ( Pwhile ) and error cleanup ( Pprotect ).

Pif(condition, iftrue, iffalse, default)
Evaluates a pattern condition that returns true or false. Then, one value is taken from the true or false branch before going back to evaluate the condition again. The default value or pattern comes into play when the true or false branch stops producing values (returns nil). If the default is not given, Pif returns control to the parent upon nil from either branch.
p = Pbind(
    \degree, Pwhite(0, 11, inf),
        // odd numbered scale degrees get a shorter rhythmic value
    \dur, Pif(Pkey(\degree).odd, 0.25, 0.5)

Pseed(randSeed, pattern)
Random number generators depend on seed values; setting a specific seed produces a repeatable stream of pseudorandom numbers. Pseed sets the random seed before embedding pattern, effectively restarting the random number generator at the start of the pattern.
p = Pbind(
        // the random seed is generated once, when creating the Pattern object
        // so the same random seed is used every time whenever this pattern object plays
    \degree, Pseed(0x7FFFFFFF.rand, Pseries({ rrand(-7, 0) }, Pwhite(1, 3, inf), { rrand(4, 10) })),
    \dur, 0.25

q = p.play;    // uses one seed

r = p.play;    // uses the same seed

// reexecute the p = Pbind... and the seed will be different
Pprotect(pattern, func)
Like the protect error handling method, if an error occurs while getting the next value from the pattern, the function will be evaluated before the error interrupts execution.
Ptrace(pattern, key, printStream, prefix)
For debugging, Ptrace prints every return value. Is your pattern really doing what you think? This will tell you. A Ptrace is created automatically by the trace message: aPattern.trace(key, printStream, prefix) --> Ptrace(aPattern, key, printStream, prefix) .
Pwhile(func, pattern)
Like while: as long as the function evaluates to true, the pattern is embedded. The function is checked once at the beginning and thereafter when the pattern comes to an end. If it's applied to an infinite pattern, there's no looping because the pattern never gives control back.
// Pwhile and Ptrace
~go = true;
p = Pwhile({ ~go }, Pbind(
    \degree, Pseries({ rrand(-7, 0) }, Pwhite(1, 3, inf), { rrand(4, 10) })
        .trace(prefix: "degree: "),
    \dur, 0.25

~go = false;    // will stop the whole pattern when the Pbind comes to an end

Previous: Pattern Guide 06d: Parallel Patterns

Next: Pattern Guide 06f: Server Control