I'm in the process of learning Scheme. I recently spent (too much!) time trying to find a bug in a program before I realized I was missing the 'else' word in a cond clause. But the behavior in such circumstances appears to be a little weird. Experimenting with the conditions with just a simple program (below) the 'whatever' gets displayed as expected in the else clause, but also gets displayed, but without the 'else', gets displayed with the surrounding double quotes and the un-interpreted new line printed literally. Can anybody explain to me what's happening? TIA.
(define (foo x)
(cond ((eq? x 0) (display "zero\n"))
(display "whatever\n")))
(define (bar x)
(cond ((eq? x 0 ) (display "zero\n"))
(else (display "whatever\n"))))
In the repl window:
Welcome to DrScheme, version 4.1.5 [3m].
Language: Pretty Big; memory limit: 128 megabytes.
> (foo 0)
zero
> (bar 0)
zero
> (foo 2)
"whatever\n"
> (bar 2)
whatever
>
"else" is just a synonym for "true". The way to read cond is as a series of tests, where the first test that's true causes that form to be evaluated.
(cond ( (test) (do this) )
( (test) (do this) ) )
Here's your first one
(cond ((eq? x 0) (display "zero\n"))
(display "whatever\n")))
cond looks at (eq? x 0)
and determined that's false. The next clause is (display "whatever\n")
. It looks at display
, and since display
is not nil
, it's true. It then evaluates the string "whatever\n"
, which simply evaluates to itself. So the value of the cond is then "whatever\n"
.
Now, here's you second one:
(cond ((eq? x 0 ) (display "zero\n"))
(else (display "whatever\n"))))
Here, the first test is false, and it goes on to the second one, which is else
and which evaluates to true. (If you think about it, that's what the "else" means in a normal if-then-else: "true for all the cases where none of the previous tests were true.")
Now, the form following it is (display "whatever\n")
. That's a function that sends the string argument to the console and returns nothing because that's what display happens to do. In another scheme, it might return its string value as well as printing it, in which case you'd see
whatever
"whatever\n"