Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / HelpSource / Tutorials / A-Practical-Guide / PG_06e_Language_Control.schelp
blob0d64b472d58d5a94274f7b1c09988928776a634c
1 title:: PG_06e_Language_Control
2 summary:: Patterns that mimic some language-side control structures
3 related:: Tutorials/A-Practical-Guide/PG_06d_Parallel_Patterns, Tutorials/A-Practical-Guide/PG_06f_Server_Control
4 categories:: Streams-Patterns-Events>A-Practical-Guide
6 section::Language control methods
8 Some patterns mimic language-style control methods: conditionals ( link::Classes/Pif:: ), loops ( link::Classes/Pwhile:: ) and error cleanup ( link::Classes/Pprotect:: ).
10 definitionList::
11 ## code::Pif(condition, iftrue, iffalse, default):: || Evaluates a pattern code::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 code::default:: value or pattern comes into play when the true or false branch stops producing values (returns nil). If the code::default:: is not given, Pif returns control to the parent upon nil from either branch.
13 code::
14 p = Pbind(
15         \degree, Pwhite(0, 11, inf),
16                 // odd numbered scale degrees get a shorter rhythmic value
17         \dur, Pif(Pkey(\degree).odd, 0.25, 0.5)
18 ).play;
20 p.stop;
23 ## code::Pseed(randSeed, pattern):: || Random number generators depend on seed values; setting a specific seed produces a repeatable stream of pseudorandom numbers. link::Classes/Pseed:: sets the random seed before embedding code::pattern::, effectively restarting the random number generator at the start of the pattern.
25 code::
26 p = Pbind(
27                 // the random seed is generated once, when creating the Pattern object
28                 // so the same random seed is used every time whenever this pattern object plays
29         \degree, Pseed(0x7FFFFFFF.rand, Pseries({ rrand(-7, 0) }, Pwhite(1, 3, inf), { rrand(4, 10) })),
30         \dur, 0.25
33 q = p.play;     // uses one seed
34 q.stop;
36 r = p.play;     // uses the same seed
37 r.stop;
39 // reexecute the p = Pbind... and the seed will be different
42 ## code::Pprotect(pattern, func):: || Like the code::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.
43 ## code::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 code::trace:: message: code::aPattern.trace(key, printStream, prefix) --> Ptrace(aPattern, key, printStream, prefix):: .
44 ## code::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.
46 code::
47 // Pwhile and Ptrace
49 ~go = true;
50 p = Pwhile({ ~go }, Pbind(
51         \degree, Pseries({ rrand(-7, 0) }, Pwhite(1, 3, inf), { rrand(4, 10) })
52                 .trace(prefix: "degree: "),
53         \dur, 0.25
54 )).play;
57 ~go = false;    // will stop the whole pattern when the Pbind comes to an end
61 Previous:       link::Tutorials/A-Practical-Guide/PG_06d_Parallel_Patterns::
63 Next:           link::Tutorials/A-Practical-Guide/PG_06f_Server_Control::