esgab26 (esgab26) wrote in lisp,

  • Mood:

Can any one help?-About the "cond" operator ----(novice)

Hi everyone,

I've read this in SICP book from MIT-OCW:

"A minor difference between if and cond is that the <e> part of each cond clause may be a sequence of expressions. If the corresponding <p> is found to be true, the expressions <e> are evaluated in sequence and the value of the final expression in the sequence is returned as the value of the cond. In an if expression, however, the <consequent> and <alternative> must be single expressions. "

so i tried this in scheme:

(define (test a b)
    (cond ((> a b) ((- a 1) (- b 1)))
               ((< a b) ((+ a 1) (+ b 1)))
               (else((+ a b) (- a b)))))

(test 3 2)

it returned: procedure application: expected procedure, given: 2; arguments were: 0

What I'm trying to do is: given a single predicate, evaluate multiple expressions (like the ones above, evaluate both (- a 1) and (- b 1)

i thought this is possible: (because of what i've read- or maybe i just don't understand it)

(cond <predicate> (<exp1> <exp2> <exp3>))- but it always result in an error

Can some one help me with this? What is meant by sequence of expressions?

Thank you very much


  • Post a new comment


    default userpic

    Your IP address will be recorded 



January 23 2009, 16:42:12 UTC 8 years ago Edited:  January 23 2009, 16:43:12 UTC

See, the thing is, you're trying to evaluate the result if (- a 1) and apply it to the result of (- b 1). What this evals to is (2 1), which is what's making Scheme cough, since you can't apply 2 to 1, given there's no function named 2.

So what you have to do is find some way to sequentially execute (- a 1), then (- b 1). Unfortunately, I don't remember what the form for this is in Scheme, but I know it's (progn) in Common Lisp. A little research on Google should help.

ETA: Google tells me the equivalent to (progn) in scheme is (begin).
You have the syntax wrong.

(cond (<predicate1> <exp1> <exp2> ...) ...)
This also works.
I suggested using (begin).
While it works, it's unnecessary in cond.
begin is for the cases, when you can't write several expression sequentially (like if), otherwise it's not necessary. Although it will surely work anywhere, where it can be omitted ;)
Eh, that's a stylistic question. :)

I use it because it makes things more readable to folks who don't know the syntax of (cond), personally.
and these guys would tell us, that funcall is ugly... :-p
Yeah, that's a good point...
An experienced reader would see an unnecessary "begin" and assume you don't know what you're doing.
Thanks, diego, xach
it's all clear now. So begin is equal to progn, gotta jot that one down.
and sussman and abelson was correct afterall.
No problem. Do return if you have any more questions.
Also, is that "else" supposed to be there? Cond will evaluate predicates until it finds one that's true, so if you want the last one to catch anything that falls through, you should use #t as the predicate.
else is a synonym for #t in most of the Scheme implementations I'm aware of.
Oh, never mind then. Wasn't aware of that.
Well, that was an accurate description of how else actually works, for anyone that didn't know, so the comment was still useful.