Table of Contents

6. Conditionals

One of the most important features of programming languages is the ability to branch off into multiple possible courses of actions based on a condition, that is, the particular state of variables or environment at a point in time.

Usually, conditions are comparisons between a changing value and a fixed value. For example, you would like to consider a shoe as "regular" or "large" based on its size:

(define shoe-size 12)

(print "The shoe size " shoe-size " is: ")
(if (> shoe-size 9)
  "large"
  "regular")

You should interpret the value after the ;; => characters as the return value of the function call. In other words, it's the result of the evaluation of the function call.

Changing the value of variables

define is used to initialize variables (to give them an initial value). For making changes to one, use (set! variable-name new-value). Although re-running (define variable-name new-value) will also work, using set! makes it clear that you are changing an existing variable.

Note the exclamation mark (!) after set. Scheme has a convention that functions ending in ! modify a value.

Now try changing shoe-size and re-running the if code:

(set! shoe-size 7)

(print "The shoe size " shoe-size " is: ")
(if (> shoe-size 9)
  "large"
  "regular")

This time, the shoe is judged to be "regular".

Booleans

To understand how if works, I need to digress a bit. There is a boolean type that I haven't talked about yet. The boolean named after the logician George Boole, and it represents a truth value.

There are only two valid values: true and false. In standard Scheme, they are #t and #f, and they will work here, but I added the aliases true and false because they are easier to read. An alias is another name for a particular thing.

The if conditional

if is the simplest conditional. It has this structure:

(if condition
  then-branch
  else-branch)

First, the condition is evaluated. The truth value of the condition is used to determine whether the then-branch or else-branch is evaluated next.

If the condition is true, the then-branch is evaluated. Otherwise, the else-branch is evaluated.

Nested expressions

The majority of code written so far relied on single expressions being evaluated from top to bottom. An expression is a unit of code, which can be a standalone value, such as "Shoes", or a list that can be evaluated: (print "I am going to buy shoes.")

In Scheme, expressions may be nested, to produce units that encompass other units. Printing a value based on a conditional can be written as:

(define apples 2)

(print "I have "
  (if (> apples 6)
    "many"
    "few")
  " apples")

It's common for Scheme functions to have five or more levels of nesting!

More than two branches

You will often need to make a decision based on more than a simple true or false value. For this purpose, there's cond.

Below is some code that returns the color of a flower based on its name. If the flower is not listed, it returns "I'm not sure". The function string=? compares two strings, returning either true or false.

(define (flower-color flower)
  (cond ((string=? flower "rose") "red")
        ((string=? flower "violet") "blue")
        ((string=? flower "sunflower") "yellow")
        (else "I'm not sure")))

Try running it with a known flower and an unknown one:

(flower-color "violet")
(flower-color "lily")

Example: conditional colors

Continuing with the colors theme, suppose we wish to draw circle outlines in one color if they are small, and in another color when they are larger. Remember that set-stroke! changes shapes' outline colors.

(define (large-is-gold size)
  (set-stroke! (if (> size 100) "gold" "gray"))
  (circle 0 0 size))

Now try drawing some circles with the new function:

(large-is-gold 50)
(large-is-gold 80)
(large-is-gold 110)
(large-is-gold 140)

As we have defined, the radii greater than 100 appear in gold.

Table of Contents