< 5. Lists | 7. First-Class Functions > |
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
.
< 5. Lists | 7. First-Class Functions > |