views:

360

answers:

3

Hi I have edited the code for function in scheme that checks whether the length of a list is even.

(define even-length?
  (lambda (l)
  (cond 
   ((null? l)#f)
   ((equal? (remainder (length(l)) 2) 0) #t)
   (else #f))))

Is it corrrect?

+2  A: 

You seem to have the syntax for if and cond all mixed up. I suggest referring to the language reference. if only has two clauses, and you don't write else for the else clause. (Hint: You shouldn't need an if for this function at all.)

Also, consider whether it makes sense to return null if the list is null; probably you want to return #t or #f instead.

Oh yeah, and rewrite your call of length to be a proper prefix-style Scheme function call.

mquander
Hi I have edited the code now.Is it correct?
nan
Closer, but `length(l)` is not the way to call a function in Scheme, and it could be much simpler; think of how to write the same thing without the `cond`.
mquander
@mquander Hi I am not able to write the function without cond.Can you help me?
nan
OK, what I was getting at was something like Jerry's suggestion. You've suffered enough, so I'll just give some code: `(define even-length? (lambda (l) (equal? (remainder (length l) 2))))` This code works because `equal?` already returns `#t` or `#f`, which is what you want from your function anyway.
mquander
Thanks mquander
nan
I missed putting the zero in that function in my comment, but I'm sure you can fill it in.
mquander
+2  A: 

The code is clearly wrong -- your %2 assuming infix notation, where Scheme uses prefix notation. The syntax of your if is wrong as well -- for an if, the else is implicit (i.e. you have if condition true-expression false-expression. In this case, you're trying to return #t from one leg and #f from another leg -- that's quite unnecessary. You can just return the expression that you tested in the if.

Edit: one other detail -- you should really rename this to something like even-length?. Even if I assume that it's a predicate, a name like even would imply to me that (even 3) should return #f, and (even 4) should return #t -- but in this case, neither works at all.

Edit2: Since mquander already gave you one version of the code, I guess one more won't hurt. I'd write it like:

(define (even-length? L) (even? (length L)))

I don't like using lower-case 'l' (but itself) much, so I've capitalized it. Since even? is built in, I've used that instead of finding the remainder.

Running this produces:

> (even-length? `(1 2 3))
#f
> (even-length? `(1 2 3 4))
#t
>

This is different from what you had in one respect: the length of an empty list is 0, which is considered an even number, so:

(even-length? `())

gives #t.

Jerry Coffin
Hi I have edited the code now.Is it correct?
nan
@nan:No -- '%' is used in C and related languages. Scheme normally calls it 'remainder'.
Jerry Coffin
Hi JerryThanks for your help.Is there any other simple function in scheme that checks whether the length of list is even.Now I have edited the code also.
nan
Offhand, I don't know of a built-in function to check whether the length of a list is even -- but there is a built-in function to check whether a number is even, which might be helpful. As mquander already pointed out, your call of `length` isn't syntactically correct yet either...
Jerry Coffin
+1  A: 
(define even-length? (lambda (l)
    (even? (length l))))

Usage:

(even-length? '(1 2 3 4))
#t
(even-length? '(1 2 3 ))
#f

As others pointed out, there is indeed a predicate to check evenness of a number, so why not using it?

EDIT: I just saw Jerry Coffin wrote the same function witht the same example... Sorry for repeating :-)

klez