Scheme Programming/Conditionals
< Scheme ProgrammingThis is a very important part of any program, as it can allow your program to make decisions, based on simple rules and the data it is given. Every Scheme standard make use of conditional expressions. Whether deciding if a number is even or odd, or if two strings are equivalent, conditionals litter most Scheme programs, and are a core part of all Turing complete languages.
In order to tackle conditionals, we must understand relational, equivalence and Boolean logic expressions
Boolean values
There are two Boolean values: True and False. In Scheme, these are represented as #t
and #f
, respectively. However, in conditional expressions, any value that isn't #f
is treated as if it were #t
.
Relational and Equivalence Expressions
These determine how one value relates to another, is x larger than y? Is x the same as y? And so on and so forth.
- (< a b)
- #t if 'a' is strictly less than 'b', #f otherwise.
- (<= a b)
- #t if 'a' is less than or equal to 'b', #f otherwise.
- (> a b)
- #t if 'a' is strictly greater than 'b', #f otherwise.
- (>= a b)
- #t if 'a' is greater than or equal to 'b', #f otherwise.
- (equal? a b)
- #t if 'a' is exactly equal to 'b', #f otherwise.
Conditionals
If
Now we know how to compare variables with one another, we can start executing code based on this, using an if
expression:
> (if (> 6 5) (+ x y) (- x y))
11
We said if expression and not statement. In most programming languages, if
is a statement. That means that in these
languages, you cannot do this:
/* Not valid Java */
int x = if (a > b) {
y;
} else {
z;
}
However, in Scheme, this is perfectly acceptable:
(define x (if (> a b) y z)) ;; Perfectly valid Scheme
In other languages, there is a separate expression-context conditional operator:
int x = (a > b) ? y : z;
The limitation is that you cannot declare new variables in expression context, so y
and z
cannot be complex expressions
that bind temporary variables. Scheme does not suffer from this limitation.
In general, an if expression has the form:
(if <Boolean> <Expression for True> <Expression for False>)
If <Boolean> is non-#f
, then <Expression for True>
is evaluated, otherwise <Expression for False>
is evaluated.
Cond
Using cond
we can easily evaluate many expressions based on a chain of predicate expressions. It is a very useful construct.
(cond ((> x 0) x)
((= x 0) 0)
((< x 0) -x))
The general form of the cond
is as follows:
(cond (<p1> <b1>) ... (<pn> <bn>) (else <body>))
Each predicate expression <p1> through <pn> is evaluated until one of them evaluates to non-#f
, and then the corresponding <body> is evaluated. If the else
clause is included, its body is always evaluated if all of the previous predicate expressions evaluated to #f
. If there is no else
and all of the predicates evaluated to #f
, then the cond
expression evaluates to the unspecified value. It is equivalent to chaining a string of if
expressions together, except without increasing the indentation level of your code.