Switch Statement



The pattern

We can use list comprehensions to simulate a switch statement.

x: _

result: [
	// case
	if x == "x" {...},
	// case
	// case

	// default
	...,
][0] // here we select the first element

This pattern has a number of if conditions or guards in a list and then selects the [0] element. By doing so, we emulate a switch statement from other languages. Be advised that all conditional statements will be evaluated.

A basic example

This example demonstrates turning an integer into a string describing its numerical classification.

switch.cue

x: 0

result: [
	if x < 0 {"negative"},
	if x > 0 {"positive"},
	"zero",
][0]

cue export switch.cue

{
    "x": 0,
    "result": "zero"
}

Order matters

In the order example, we show our work by breaking down the pattern. While a “true” prefix has the correct result, we can see that when a and b are the same, HasPrefix still matches and we get the less accurate result.

order.cue

import "strings"

#compare: {
	a: string
	b: string
	l: [
		if strings.HasPrefix(b, a) {"prefix"},
		if a == b {"same"},
		"none",
	]
	result: l[0]
}

ex1: (#compare & {a: "a", b:   "abc"})
ex2: (#compare & {a: "abc", b: "abc"})

cue export order.cue

{
    "ex1": {
        "a": "a",
        "b": "abc",
        "l": [
            "prefix",
            "none"
        ],
        "result": "prefix"
    },
    "ex2": {
        "a": "abc",
        "b": "abc",
        "l": [
            "prefix",
            "same",
            "none"
        ],
        "result": "prefix"
    }
}

An uncovered case errors

We can modify our first example to demonstrate what happens when you forget the default, or otherwise fail to cover all conditions.

uncovered.cue

x: 0

result: [
	if x < 0 {"negative"},
	if x > 0 {"positive"},
][0]

cue export uncovered.cue

result: index out of range [0] with length 0:
    ./uncovered.cue:6:3

All conditions are evaluated

You might expect the following to work rather than error. This is the result of all conditions being evaluated. That is, there is no short-circuit to the evaluation.

conditions.cue

l: []

result: [
	if len(l) == 0 {"empty"},
	if l[0] {"starts with true"},
][0]

cue export conditions.cue

index out of range [0] with length 0:
    ./conditions.cue:5:7
We'll never share your email with anyone else.
2022 Hofstadter, Inc