Actually it may make some sense to very briefly explain the different behaviours of the 3 main functions which operate on Time State:
get
- this simply retrieves the latest value at the current time (or no value if none is found). This does not block the current thread in any way and is assumed to take 0 time.set
- this puts a value at the current time into the Time State. It does not block the current thread and is assumed to take 0 time.sync
this retrieves the next value from the current time and if no value is already there and waiting it will block the current thread. The amount of time this takes depends on when the next value is available. You can therefore treatsync
like a special kind ofsleep
where you don’t specify the time explicitly - rather it’s just the time of the next matching event.
Actually, this does make the playchord
live loop drift. After 1000 iterations, it will be 1 second later than other other thread. 0.001
is only a small amount but it slowly adds up over time. If you don’t want drift like this, consider at
and time_warp
.
I’m not sure there is no right in conventional programming. It depends entirely if you want non-deterministic behaviour or not. Sonic Pi attempts to ensure that the same code always produces the same sounds as this makes collaboration and re-creation possible which I believe to be extremely powerful for production.
Indeed. The puts
statements send the values to be printed to the GUI. This part of the system is non-deterministic - it sends messages over the local loopback network via UDP so there are no guarantees on order of delivery which is why you see the print outs in different orders each time you run. However all the internal events within the language are deterministic - it’s just the GUI that’s not
Hope that this helps!