yrazlik
yrazlik

Reputation: 10777

What is wrong with my code in determining palindrome in scheme?

I am trying to detect the palindrome lists in scheme. Here is my code:

;- Input : Takes only one parameter named inSeq
;- Output : It returns the reverse of inSeq if inSeq is a sequence.
; Otherwise it produces an error.
;- Examples :
; (reverse-sequence '(a b c)) --> evaluates to (c b a)
; (reverse-sequence '()) -------> evaluates to ()
(define reverse-sequence
 (lambda (inSeq)
   (if (sequence? inSeq)
       (if (null? inSeq) 
           inSeq 
           (append (reverse-sequence (cdr inSeq))
                   (list (car inSeq)))))))

;- Input : Takes only one parameter named inSeq
;- Output : It returns true if inSeq is a sequence and it is a palindrome.
; It returns false if inSeq is a sequence but not a plaindrome.
; Otherwise it gives an error.
;- Examples :
; (palindrome? '(a b a)) --> evaluates to true
; (palindrome? '()) -------> evaluates to true
; (palindrome? '(a 1 a)) --> produces an error
(define palindrome
 (lambda (inSeq)
   (if (sequence? inSeq) 
       (if (equal? reverse-sequence(inSeq) inSeq ) 
           #t 
           #f))))

When i try the input '(a b a) i get the following error:

The object (a b a) is not applicable

Can anyone help me with this error? Thanks

Upvotes: 1

Views: 2059

Answers (2)

Óscar López
Óscar López

Reputation: 236004

Remember, in Scheme the correct way to invoke procedure f on argument x is: (f x). That explains why this snippet doesn't work:

reverse-sequence(inSeq)

It should have been:

(reverse-sequence inSeq)

Be aware that you'll run into trouble if the argument received isn't a sequence, you'll get a void value and you won't get a correct answer. Also, you could have used the built-in reverse procedure, but I guess you want to implement it yourself - with that in mind, it'd be a better idea to reverse the list accumulating the result in a parameter (tail recursion), so you don't have to append the results (which is expensive), just cons the results (which is very cheap). This is what I mean:

(define (reverse-sequence inSeq)
  (if (not (sequence? inSeq))
      '()  ; can't reverse if it's not a sequence
      (let loop ((inSeq inSeq)
                 (reversed '()))
        (if (null? inSeq)
            reversed
            (loop (cdr inSeq) (cons (car inSeq) reversed))))))

(define (palindrome inSeq)
  (if (not (sequence? inSeq))
      #f
      (equal? inSeq (reverse-sequence inSeq))))

Upvotes: 2

GoZoner
GoZoner

Reputation: 70165

You wrote

(equal? reverse-sequence(inSeq) inSeq )

which tries to call (inSeq) as a function of no arguments. It should read:

(equal? (reverse-sequence inSeq) inSeq )

Upvotes: 3

Related Questions