Multiple conditional inputs for one or two outputs

I can’t figure out how to create multiple inputs for one or two outputs like this: If (1 = 1, 2 = 2, 3 = 3 etc.) than {true function to be executed} otherwise {false function or nil}.But I also need a function to be true only if all conditions are present and true otherwise false function or nil.So “if” statement could be also like this if (1, 2, 3, 4 = 4, \or_some_symbol {true}, {false}.This is kind of some specific combination of inputs for

This is what you’re looking for: Boolean | SuperCollider 3.11.1 Help

case and switch both offer multiple conditional statements… the syntax is very specific.

~input = [1, 2]

case{ ~input.size === 1 }{ 'one' }{ ~input.size === 2 }{ 'two' }{ postln("unevaluated") }

case{ ~input.size === 1 }{ 'one' }{ ~input.size === 2 }{ 'two' }; { "this will simply post 'a Function'" }

case{ ~input.size === 1 }{ 'one' }{ ~input.size === 2 }{ 'two' }; postln("default behavior")

~input = #[1, 2, 3]

switch(~input.size) { 1 }{ 'one' } { 2 }{ 'two' } // nil

switch(~input.size, { 1 },{ 'one' }, { 2 },{ 'two' }, { postln("default behavior") }) // default behavior

switch(~input.size) { 1 }{ 'one' } { 2 }{ 'two' }{ 3 }{ 'three' }{ postln("unevaluated because ~input.size == 3") } // three

switch(~input.size) { 1 }{ 'one' } { 2 }{ 'two' }{ 3 }{ 'three' }; { "this will simply post 'a Function'" }

~input = [$1, 2.0, \3, 4]

if(
    ~input.notNil && { ~input.isKindOf(Collection) && { ~input.notEmpty } }
)  {
    switch (~input.size)
    { 1 }{ 'one' }
    { 2 }{ 'two' } 
    { 3 }{ 'three' }; 
   ~input.do{ |x, n| postf("(object #% -> %) %", n, x.class, $\n)}
} {
    inform("not everything was true")
}

It may difficult to grasp, at first glance, which version of syntax is more conducive to one’s true intent.

I typically use if or switch, and/or iterate over a collection using collect or collectInPlace

collect returns a new collection without altering the original… while collectInPlace returns and permanently alters the original collection object.

I rarely use for forBy case while etc… all can be found in the documentation, under control structures.

The block keyword is a bit esoteric, however, it can be quite useful once you become familiar with the technique… block allows you to create and arbitrary killswitch, which will allow you to break from any loop or stream… including do, for, while, etc.

There’s no strict rules or convention, however, it’s usually wise to stay consistent, in terms of style (syntax) and format (indentation, placement of brackets and newline characters).

I found the control structure doc less then perfectly clear at first… this should clarify the finer points of the differences in the syntax implementations.

With if and switch, the syntactical differences are perfect reflections of each other… only the keywords change, and number of possible conditions.

if (commas, function style):
if(~condition, { \true }, { \false })

if (commas, open style)
if(~condition, \true, \false)

if (commas, open style, true only)
if(~condition, \true)

if (commas, open style, true only, w/ default)
if(~condition, \true); \default

if (no commas, function)
if (~condition){ \true }{ \false }

if (no commas, function, true only)
if (~conditional) { \true }

if (no commas, function, true only, w/default)
if(~condition){ \true }; \default

Using the ‘true only’ versions will usually return nil… however, there are a few special cases, in which the return value is simply “no value”, or the receiver remains unchanged.

a = [1, 2, 3, 4, 5, 6]

a.insert(5, if(true) \zero) // inserts nil
a.addAll(if (true) \zero) // adds nil
a.add(if (true) \zero) // adds \zero
a.add(if (false) \zero) // a → [1, 2, 3, 4, 5, 6]

Thanks, Rainer! I was aware about “control structures”, but all these examples show just one input against one output at a time or conditional function execution. “Case” and “switch” always outputs last true line, but doesn’t take care if multiple (or specific ones) of them was true or false at once. Though now I have an intuition from your last “if + switch” example. If I want something previously described some kind of iteration (with “do”, “while” etc.) over case is needed, am I right?

Can you please comment more on this example?

So, in this case, the intial condition to the if statement, is provided for the sake of highlighting the syntax of having multiple conditional statements, in a singleton instance of your if conditional expression.

~test_1 || { ~test_2 } // if either/or are true

~test_1 && { ~test_2 } // if 1 and 2 are true

Remember to use the enclosing brackets, which are required for all conditionals beyond the initial test.

You can nest as many if case while switch do collect etc… i.e. control constructs within as many layers/levels of other control constructs… as many as one can fathom.

Some possibilities are:

i = [1, 2, 3]

o = switch (i.size){ 1 }{ \one } { 2 }{ \two } { 3 }{ \three } // o -> \three

or:

switch (i.size){ 1 }{ post(\one) } { 2 }{ inform(\two) } { 3 }{ postln(\three) }

…just remember that syntax is never the answer… the truth usually stems from a wish or desire, a feeling or an effect… or a sensation… or a movement…

These simple forms of logical architecture are the underlying implementations for all computer programming languages… they are made to bend to our will… they are made to do only as we wish… the best practice in all of programming is “the clarity and efficiency of one’s true expressive intent”, for even though there are always an infinite number of ways to do something… and even though sometimes the transparency of your code may seem far less important than the actual manifest (stage lighting or musical compositions)… still, its always a wise choice to keep your intent clearly focused, for whenever you want to improve manifest, there will always be another who can clearly light it.

1 Like

This community never shoots down a question.

:slight_smile: What kind of questions? Like “why do you want this or that?”

1 Like