0
votes

Hey, I'm trying to use and in a cond statement. Basically, instead of simply checking that <exp1> is true before running some code, I need Scheme to check that <exp1> AND <exp2> are true. I understand that (and #t #f) evaluates to #f and that (and (= 10 (* 2 5)) #t) evaluates to #t. Unfortunately, Scheme will not accept

(and (eqv? (length x) 1) (eqv? (car x) #t))

where x is a list whose first element is an S-expression that evaluates to either #t or #f (in fact, I wanted to just do (and (eqv? (length x) 1) (car x)), but that didn't work).

Can anyone explain what I am doing wrong, or how to fix it? On a side note, does anyone know what ... means in Scheme, if anything? Thanks!

2
You are sure that (car x) shows up as either #t or #f? - Josh K
Are you trying to implement and or are you trying to use it? In general, your question is very unclear, and suffers from really bad formatting that hides some of the text. Without sorting it out it would be very difficult to say anything. - Eli Barzilay

2 Answers

3
votes

"where x is a list whose first element is an S-expression that evaluates to either #t or #f (in fact, I wanted to just do (and (eqv? (length x) 1) (car x)), but that didn't work."

In the second case of (car x), you just get the first element in the list, you do not evaluate it.

Say your list x is a list ((eq? 3 3)), I'm just saying something. Its length is 1, and it's first element evaluates to #t if we evaluate it, but (car x) in this case retrieves a list (eq? 3 3), which is a list of one symbol and two numbers.

The solution to your problem would be using eval, as in (eval (car x) (null-environment)), which evaluates a datum, such as a list.

If you use ((car x)) as noted in another answer, this will only work if your first element of a list is a thunk, a nullary, if you constructed x by evaluating the list (list (lambda () #t)).

In that case, your first element would be a function which when called with no arguments yields #t.

0
votes

This works (define l1 '(#t #f #t))

(car l1)
; #t    
(and (car l1) (car (cdr l1)))
; #f

But this doesn't

(define l2 '((eq? 1 1) (eq? 1 2)))

(car l1)
; '(eq? 1 1)  
(and (car l1) (car (cdr l1)))
; fails

Which are you trying to do?

If the second, then consider evaluating the expression before entering it into the list, if possible.

Or you could try:

(define l3 (list eq? 1 1))

l3
; '(#<procedure:eq?> 1 1)

(apply (car l3) (cdr l3))
; #t