Question

I am new to the Scheme language. I am reading the "simple scheme" book and came across the next example:

(cond (empty? 3)
      (square 7)
      (else 9))

When I run it I got 3. I know that each cond expression need to take 2 args: the one for "eval" of the condition and the second is the "answer". Where is the eval and where is the answer ? Why ?

Was it helpful?

Solution

This is not a real-world example.

As you correctly understood, each clause has a condition and a result. The conditions are: empty?, square and else. The answers are 3, 7 and 9.

cond will look for the first condition that evaluates to #t. In Scheme, everything is #t except #f. So the first condition evaluates to true:

> (if empty? "true" "false")
"true"

and cond returns the first result, 3.

OTHER TIPS

The correct way to write a cond expression looks like this:

(cond ((even? 3) 3)
      ((odd?  5) 5)
      (else -1))

So you see, the predicate expressions are in the left part of each clause and if any of them is true then the expressions to its right are evaluated, returning the last value; in the above example 5 is returned.

Regarding your code, this is what's happening: the empty? function is taken as #t (because in Scheme anything that's not explicitly #f is considered true), so the first clause is true and the expression to its right is evaluated and returned, which happens to be 3. You can easily verify this behavior, for instance the following snippet will return "ok" because once again the function name empty? is considered true:

(if empty? "ok" "not ok")

The syntax for cond is:

(cond <clause1> <clause2> …)

where clauses are:

(<test> <expression1> …)

or

(<test> => <expression>)

and the last <clause> can be (else <expression1> <expresssion2> …). Thus, ignoring the => case, a cond expression looks like:

(cond (<test> <exp1> <exp2> …)
      … 
      (else   <exp1> <exp2> …))

If you match this up with your expression:

(cond (empty? 3)
      (square 7)
      (else 9))

you see that empty?, the identifier, is a <test> which will always be a true if empty? is bound. The identifier square is another <test>. That is not what you intended.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top