1.4 Conditionals

The if form works in the usual way, and it follows the parenthesized-prefix convention of being grouped with its subexpressions with parentheses:

> (if (equal? "apple" "banana")
      'yes
      'no)

- Symbol

'no

The line breaks above don’t matter to Plait, but readers of your programs will appreciate it if you normally put the “then” and “else” branches on their own lines and correctly intent them. The correct indentation is the indentation that DrRacket gives you automatically when you hit Return after (equal? "apple" "banana"). If you ever need to reindent a region of code, you can select the region and hit Tab.

The cond form is a multi-way if. A cond form has a sequence of clauses, where each clause has a “question” and a result expression. The result expression is used only when the question produces true. The cond form tries the clauses in order, and as soon as it finds a true result from a question, it produces the corresponding result. The last clause’s question cal be else as a synonym for #t.

> (cond
    [(< 2 1) 17]
    [(> 2 1) 18])

- Number

18

> (cond
    [(< 2 1) (/ 1 0)] ; result expression skipped
    [(> 2 1) 18])

- Number

18

> (cond
    [#t 8]
    [#t (/ 1 0)]) ; second clause not reached

- Number

8

> (cond
    [(< 3 1) 0]
    [(< 3 2) 1]
    [(< 3 3) 2]
    [(< 3 4) 3])

- Number

3

> (cond
    [(eq? 'a 'b) 0]
    [(eq? 'a 'c) 1]
    [else 2])

- Number

2

Plait doesn’t distinguish between square brackets [ and ] and parentheses ( and ), as long as each opener and closer match. You could use parentheses instead of square brackets in the above examples—but don’t. Plait programmers should use square brackets in specific places by convention to make programs more readable. Follow the conventions that you see in this tutorial.

The and and or forms are short-cicuiting, too, and they work with any number of boolean subexpressions:

> (and #t #t)

- Boolean

#t

> (and #t #f)

- Boolean

#f

> (and (< 2 1) #t)

- Boolean

#f

> (and (< 2 1) (zero? (/ 1 0))) ; second expression is not evaluated

- Boolean

#f

> (or #f #t)

- Boolean

#t

> (or #f #f)

- Boolean

#f

> (or (< 1 2) (zero? (/ 1 0))) ; second expression is not evaluated

- Boolean

#t

> (and #t #t #t #t)

- Boolean

#t

> (or #f #f #f)

- Boolean

#f