Search code examples
lispracketsicp

about racket remainder expected params


recently, i'm learning sicp but I meet a strange question :

Error:
remainder: contract violation
  expected: integer?
  given: '(3 4 5 6)
  argument position: 1st
  other arguments...:
   2

here's my code

   (define (same-parity sample . other)
      (if (null? other)
          (cons sample '())
          (if (= (remainder sample 2) (remainder (car other) 2))
                  (cons (car other) (same-parity sample (cdr other)))
                  (same-parity sample (cdr other)))))

    (same-parity 1 2 3 4 5 6)
  1. os: win10
  2. lang: racket v6.10.1

It tell remainder expected a integer param I think I given a integer to remainder not a list. So can someone tell my what's wrong with my code. I am in a great quandary. thank in advance.


Solution

  • This error happens because your procedure operates on an unknown number of multiple arguments - that's what the . means when declaring the procedure, and other is interpreted as a list of args. It passes the right args when the procedure is invoked, but the first time we call the recursion, it fails.

    One solution is to make sure that we always apply the procedure on multiple arguments, instead of passing a list as the second argument, which is what your code is doing now, causing the error. Try this:

    (define (same-parity sample . other)
      (if (null? other)
          (cons sample '())
          (if (= (remainder sample 2) (remainder (car other) 2))
              (cons (car other) (apply same-parity sample (cdr other)))
              (apply same-parity sample (cdr other)))))