Brandon Smith
Brandon Smith

Reputation: 7

What does this error mean in Scheme: "and: bad syntax in: and"?

I am getting the following error "and: bad syntax in: and":

(define test (lambda(list1 a b c d)
    (cond (null? list1)
       (and (eqv? a b) (eqv? c d))
       (two-subsets (cdr list1) a b c d))))

(test '(1 2 3 4) 0 0 0 0)

Essentially I am trying to make the following recursive call as a base case (equivalent in java):

return (a == b && c == d);

Upvotes: 0

Views: 2490

Answers (1)

Sylwester
Sylwester

Reputation: 48745

a == b && c == d is (and (eqv? a b) (eqv? c d)), however you are using cond wrong. The right way is:

(cond
  (predicate-expression consequence-expression ...)
  ...
  (else alternative-expression ...))

Your attempts look like this:

(cond
  (null? list1)
  (and (eqv? a b) (eqv? c d))
  (two-subsets (cdr list1) a b c d))))

That makes null? the predicate and list1 the consequent. Since null? is a procedure it cannot be #f and thus your cond should return list1 always. Because and is not allowed to be evaluated on its own and it is a macro you get a compile time error.

I have no idea what you are trying to do with that cond since if I add parentheses I get this:

(cond
  ((null? list1) #t)
  ((and (eqv? a b) (eqv? c d)) #t)
  (else (two-subsets (cdr list1) a b c d))))))

This is based on that a cond terms with no consequences return their true value and both null? and eqv? return #t when it's not #f. It also clear that this can be replaced with #t since that is always the result no matter what the arguments are.

cond is not a primitive and it just translated your code to if. Just for fun here is what your original cond gets translated to:

(if null? 
    list1
    (if and
        (begin
          (eqv? a b)  ; dead code
          (eqv? c d))
        (if two-subsets
            (begin
              (cdr list1) ; dead code  
              a           ; dead code 
              b           ; dead code
              c           ; dead code
              d)
            'undefined-return-value))) ; no  else clause

Upvotes: 2

Related Questions