Scheme Programming/Conditionals

From Wikibooks, open books for an open world
Jump to: navigation, search

This 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[edit]

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[edit]

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.



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))

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) {
          } else {

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.


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.