Hm, except that your SynthDef says |freq = 60...| – the rrand value is not known to the SynthDef at the time of building it.
There’s a brief mention of synth argument handling here but granted, this isn’t likely to be found from beginning tutorials.
First concept: If a value is changing in the server, then it must be a signal. The server can’t change anything about the structure of a SynthDef. A hardcoded number is part of that structure; so if a number needs to be not-hardcoded, then it must be a signal.
Second concept: the Control UGen. Control is unique because it takes input from the language client (instead of taking input from other UGens, like most units do). Function arguments are consolidated first, by category, and then one Control unit is made per category (except literal arrays, which would be folded in with the normal kr args).
The SynthDef here has |freq = 60, amp = 0.1, gate = 1, wowrelease = 3|, so the SynthDef builder finds four arguments, no special cases. So the first thing in the final SynthDef is a Control UGen, with 4 channels, associated with the names freq, amp, gate and wowrelease. (You can .trace a running Synth, and if you do, you’ll find that the first unit is Control, with 4 output values for this SynthDef.) Each of the 4 channels is represented by an OutputProxy; during SynthDef building, freq is assigned the first OutputProxy, amp is assigned the second, and so on. The default values of these output channel proxies are taken from the argument list too.
At Synth(\wow, [freq: rrand(40, 70)...]) time, the OSC message to the server includes a pair of arguments "freq", 53 (for instance). When the synth starts playing, the Control output channel for frequency is set to the value 53 then (or whatever is in the OSC message – 53 could be replaced by any valid rrand result).
freq.lag(2) applies a Lag filter to the control signal coming from the Control UGen (to the freq channel, not the other channels).
James McCartney said once that he thought it might have been a mistake to auto-promote function arguments to synth controls, because the relationship between args and Control channels is, erm, less than obvious. And others have argued that everyone should always write synth controls as e.g. \freq.kr(60) (though I think that case was overstated, and I continue to use function args for normal, single-valued kr controls).
I guess that tutorials don’t go into this at the initial stages because it’s a rather large ball of concepts to throw at a new user. But agreed, it would be better if Getting Started had some links to a more complete description.
hjh