Skip to content

Control Flow

There are several ways to control the flow of a program, particularly through if-statements and select-statements. These constructs enable decisions in the program based on conditions or values, guiding the execution through different paths.


If-Statements

The if-statement is the most basic form of conditional logic. It allows the execution of a block of statements when a certain condition is true and, optionally, an alternative block if the condition is false.

Basic Syntax of If-Statement

The syntax of a simple if statement consists of a condition, an if block, and an optional else block. If the condition is not met, the else block is executed, and vice versa.

In the following example, the message "Value is greater than 3" is printed if the condition value > 3 is true. If value is exactly 3, the message "Value is 3" is printed; otherwise, "Value is 3 or less" is displayed.

1
2
3
4
5
6
7
8
9
declare value := 5

if (value > 3)
    message("Value is greater than 3")
else if (value = 3)
    message("Value is 3")
else
    message("Value is less than 3")
end if

In CKSP syntax, it's not required to use parentheses around the condition in an if statement. The condition can be written directly.

Additionally, CKSP supports the use of else if, as shown above, which simplifies checking multiple conditions in a single statement chain.


Ternary Expressions

0.0.7 experimental

The ternary expression is a compact way to perform conditional evaluation within an expression. It is written using the ? and : operators and has the form:

condition ? expr_if_true : expr_if_false

The condition is evaluated first. If it is true (nonzero), the expression after ? is evaluated; otherwise, the expression after : is evaluated. The conditions are executed like normal KSP if-statement conditions, thus using short-circuit evaluation. Moreover, the compiler also uses short-circuiting when function calls are involved, meaning that only the necessary function is called based on the condition.

Basic Usage

In this example, the value of x is tested, and either "Positive" or "Negative" is assigned to the variable result:

1
2
3
declare x := 5
declare result := x > 0 ? "Positive" : "Negative"
message(result)

This behaves equivalently to the following if-else statement:

declare x := 5
declare result: string

if (x > 0)
    result := "Positive"
else
    result := "Negative"
end if

message(result)

Using Ternary in Expressions

Ternary expressions can appear directly inside larger expressions, such as function arguments or arithmetic:

message( value < 10 ? 0 : 1 )

Here, the message function prints 0 if value is less than 10, otherwise 1.

Nested Ternary Expressions

Ternary expressions are right-associative, meaning nested expressions are evaluated from right to left:

1
2
3
declare midi_note := 64
declare label := (midi_note > 72 ? "High" : midi_note > 60 ? "Mid" : "Low")
message(label)

This is equivalent to:

declare midi_note := 64
declare label: string

if (midi_note > 72)
    label := "High"
else if (midi_note > 60)
    label := "Mid"
else
    label := "Low"
end if

message(label)

Notes on Ternary Expressions

  • Ternary expressions can be used wherever a value is required (assignments, arguments, return values).
  • For complex logic or multiple nested conditions, if-else statements may be clearer and easier to read.

Use ternary expressions for concise logic

Ternary expressions are best suited for short, inline conditions. For more extensive conditional logic, prefer if-else or select statements for readability.


Select-Statements

The select-statement provides another way to control program flow based on the value of a variable, an expression, or a function's return value. It resembles the if statement but with the advantage of supporting multiple branches (cases). Similar to if, parentheses around the selected expression are optional.

As soon as the value of the expression matches a case branch, that branch is executed, and the select statement exits.

declare direction := 0

select (direction)
    case -1
        message("Moving left")
    case 0
        message("Standing still")
    case 1
        message("Moving right")
    case default
        message("Invalid direction")
end select

default branch

CKSP provides the option to use a default branch in a select statement to perform a default action when none of the case branches match.

In this example, the value of direction is evaluated, and the corresponding case branch is executed. If direction equals -1, "Moving left" is printed; for 0, "Standing still" is displayed, and for 1, "Moving right" is shown. The default branch is executed when no other case matches.

Value Ranges in Select-Statements

Moreover, case branches can cover ranges of values. This is done using the to keyword, which allows checking for a span of values.

Value Ranges in Select-Statements
select (CC[VCC_PITCH_BEND])
    case -8191 to -1
        message("Pitch Bend down")
    case 0
        message("Pitch Bend center")
    case 1 to 8191
        message("Pitch Bend up")
    case default
        message("Invalid Pitch Bend value")
end select

Here, the select statement checks the value of CC[VCC_PITCH_BEND] across a range. The first branch covers values from -8191 to -1, the second for exactly 0, and the third for values from 1 to 8191. The default branch handles any other cases outside these ranges.