views:

47

answers:

2

Hi all, I´v tried to write a procedure that gets an integer as parameter and returns true if the number is a palindrome and false otherwise and it seems to be that there is a problem with changing a global parameter's value whithin an internal function block.

(define index 0) 
(define (palindrome? x) 
  (if (= (lenght x) 1)
      #t
      (if (last_equal_first x)
          (palindrome? (remove x))
          #f)))
(define (lenght x) 
  (define index **(+ index 1))**
  (if (= (modulo x (ten_power index)) x)
      index
      (lenght x)))

(define (last_equal_first x)
  (if (= (modulo x 10) (modulo x (/ (ten_power (lenght x)) 10)))
      #t
      #f))

I would like to know what can I do about it thanks!

+1  A: 

Well, one problem is that you're redefining index after it's been used, in the length function. define doesn't really do what you want here - you want set!.

However, I think you'll find another bug when you try to call the length function more than once - you never set index to 0 after the first time, so I believe your length function will only work once.

However, this seems like it might be a homework assignment. Would you like clear instructions on fixing these problems, or would you like clues that lead you to understand the algorithm more?

Noah Lavine
A: 

What that (define ...) statement does in lenght is create a new variable called "index" that is more locally scoped than the "index" you defined at the top. That's only the superficial problem---more importantly, it looks like you're trying to write C code using Scheme. In a simple homework assignment like this, you should not need to use global variables, nor should you ever have to change a variable once it's created. Many programmers have trouble shifting how they think when first learning functional programming.

The way you've written lenght is not so much recursion as just a glorified while loop! There is no point to recursion if (lenght x) only calls (lenght x) again. For example, here's how I would write digits to count how many base-10 digits are in a number:

(define digits
  (lambda (n)
    (letrec ([digit-helper (lambda (n index)
                             (if (= (modulo n (expt 10 index)) n)
                                 index
                                 (digit-helper n (add1 index))))])
      (digit-helper n 0))))

Notice how I never change a variable once it's been created, but only create new variables each time. Since I need to keep track of index, I created helper function digit-helper that takes two arguments to mask the fact that digit only takes one argument.

erjiang