1.4 Conditionals🔗ℹ

An if has a “test” expression followed by a vertical bar | before the “then” expression, and then another vertical bar | before the “else” expression. An “else” expression is required.

> if "apple" == "banana" | #'yes | #'no

- Symbol

#'no

> if "apple" == "banana" | #'yes

if: expected more terms

A | can start on its own line. If the first | starts on its own line, then the | must be vertically aligned with if. A later | on its own line must be aligned with the first |.

> if "apple" == "banana"

  | #'yes

  | #'no

- Symbol

#'no

> if "apple" == "banana" | #'yes

                         | #'no

- Symbol

#'no

DrRacket can help you indent by the right amount. Hit the Tab key to cycle through syntactically valid indentations for the current line. Note that if your line doesn’t yet start with |, then DrRacket will offer different choices than when the line does start with |.

The cond form is a multi-way if. A cond form has a sequence of clauses, each starting with |. A clause has a “question” and a result expression, and those two parts are separated with a colon :. When cond runs, the result expression is used only when the question expression produces #true. The cond form tries the clauses in order, and as soon as it finds a #true result from a question, it returns the corresponding result. If there’s no #true result from any question, and error is reported. The last clause’s question can be ~else as a synonym for #true.

> cond

  | 2 < 1: 3

  | 2 > 1: 4

- Int

4

> cond

  | 2 < 1: 1/0 // result expression skipped

  | 2 > 1: 4

- Int

4

> cond

  | #true: 3

  | #true: 1/0 // second clause not reached

- Int

3

> cond

  | 3 < 1: 0

  | 3 < 2: 1

  | 3 < 3: 2

  | 3 < 4: 3

- Int

3

> cond

  | 2 < 1: -3

  | 2 < 0: 1-4

- Int

cond: no matching case

> cond

  | "a" == "b": 0

  | "a" == "c": 1

  | ~else: 2

- Int

2

The rules for starting a | on a new line are the same for any form, whether it’s if, cond, or something else. So, a cond form could be written on a single line, although that’s usually not as readable.

> cond | "a" == "b": 0 | "a" == "c": 1 | ~else: 2

- Int

2

General rules also apply to newlines after :. The content after a : can start on its own line, as long as it’s more indented that the content before :. The indentation doesn’t need to be more than the : itself—only more than the content before the :. If that content is in a [|], then the start of the content is after the |.

> cond

  | "a" == "b":

      0

  | "a" == "c":

      1

  | ~else:

      2

- Int

2

“And” and “or” operations are written with && and || infix operators. The && and || forms are short-circuiting, which means that they stop as soon as a #true or #false result is determined.

> #true && #true

- Boolean

#true

> #true && #false

- Boolean

#false

> 2 < 1 && #true

- Boolean

#false

> 2 < 1 && 1/0 == 0 // second expression is not evaluated

- Boolean

#false

> #false || #true

- Boolean

#true

> #false || #false

- Boolean

#false

> 1 < 2 || 1/0 == 0 // second expression is not evaluated

- Boolean

#true

> #true && #true && #true

- Boolean

#true

> #false || #false || #false

- Boolean

#false