"conditional composition"

So i’ve been getting deep into “conditional composition” and Pif is super convenient for this in most cases. It does, however, get confusing and laborious when multiple cases are stated. At the moment I achieve this by nesting multiple instances of Pif.
It would probably be easier to do this sort of thing with a switch in a routine or, come to think of it, Pfunc.
Oh well, I’m really just curious about other techniques you folks are employing that would be characterized as “conditional composition”.
This concept super exciting to me and is probably the main draw for me with supercollider as conventional daws really doesn’t offer it as a functionality. At least not in the general sense that is possible in SC.

So, please share!

I don’t know anything about conditional composition, i found this paper https://link.springer.com/article/10.1007/BF01211001 but it’s way too mathematical for me. Can you share some code and some quick explanation of the concept ?

I don’t know, man, but that paper is about function composition – i think the OP was more getting at alternative bases for Belnap’s four-valued logic, maybe to provide complete equational axiomatizations for them. One is called conditional composition logic. It has a single, ternary if-then-else connective with a sequential, operational reading, and four constants for the truth values. The other logic is called guard logic. The main motivation for this logic lies in its technical properties. It admits a useful type of canonical form (term representation), and a relatively simple strategy for equational reasoning.

I could be wrong, though. Who knows.


All jokes aside, if you use patterns, you may want to check out things like

Prout. Allows you to write your “compositional logic” as if it were a function, and you can “yield” (think of it as a kind of return) values from it. The difference with a normal function is that the next time Prout gets called, it simply continues execution from where it last yielded a value.

Plazy allows you to return a pattern from a function. In the function you can have conditions to decide what kind of pattern to return e.g.

Pfunc Allows you to return a value from a function.

Yeah i’ve been playing around with these. I’m just getting in the habit of relying on Pif for the most part. Combining it with various sorts of data sharing from different patterns and elements brings interesting results.
If I allow myself to dream I’d love if there was a switch equivalent to Pif with case and default statements like in C instead of simple boolean.

FR …@ChrisOrstedt …if you’re feeling enterprising you might write this! (Pcase)

You could do this in a Pfunc

Post some code, you’re sure to get more suggestions.


Hmm well that could be the yak i end up shaving.

You’re right.

~kick = Pbindef(\kickPat,
	\instrument, \kick,
	\dur, 0.25,
	\amp, Pseq(Bjorklund(13, 35, inf), inf)
~psKick = PS(~kick, inf, 4, 1);

~snr = Pbindef(\snrPat,
	\instrument, \snr,
	\dur, 0.25,
	\amp, Pif(Pfunc{~psKick.lastValues[3][\amp]>0} && Pfunc{~psKick.lastValues[0][\amp]<1}, Pseq([0, 1], inf),0)
~psSnr = PS(~snr, inf, 4, 1);

This is the sort of thing I like doing. The above example is obviously simplified but you can get some interesting “generative” structures and rhythms when a bunch of things are interacting with a bunch of other things.
@dkmayer’s PSx stream patterns are super useful for this as it allows for data sharing of past events in a neat manner. Still digging through that suite though and trying to find an optimal way of integrating it into my workflow.

1 Like

Psym / Pnsym are very good for choosing one pattern among several options to embed (that is, playing each subpattern through to completion).

Psym1 / Pnsym1 are similar, but make the selection per event (analogous to Pif).

Those use symbols to choose the option. Pswitch and Pswitch1 use numeric indices for the same.

With these, you aren’t limited to binary/Boolean selection – you can have as many as you need.


1 Like