Conditional Recursion Error in Scheme, returns a string when it expects a procedure

StackOverflow https://stackoverflow.com/questions/22923768

  •  29-06-2023
  •  | 
  •  

Domanda

(define (toHexm h)    
(if (> h 15)
    (cond
     ((= (modulo h 16) 1) ((string-append "1" (toHexm (floor(/ h 16))))))
     ((= (modulo h 16) 2) ((string-append "2" (toHexm (floor(/ h 16))))))
     ((= (modulo h 16) 3) ((string-append "3" (toHexm (floor(/ h 16))))))
     ((= (modulo h 16) 4) ((string-append "4" (toHexm (floor(/ h 16))))))
     ((= (modulo h 16) 5) ((string-append "5" (toHexm (floor(/ h 16))))))
     ((= (modulo h 16) 6) ((string-append "6" (toHexm (floor(/ h 16))))))
     ((= (modulo h 16) 7) ((string-append "7" (toHexm (floor(/ h 16))))))
     ((= (modulo h 16) 8) ((string-append "8" (toHexm (floor(/ h 16))))))
     ((= (modulo h 16) 9) ((string-append "9" (toHexm (floor(/ h 16))))))
     ((= (modulo h 16) 10) ((string-append "A" (toHexm (floor(/ h 16))))))
     ((= (modulo h 16) 11) ((string-append "B" (toHexm (floor(/ h 16))))))
     ((= (modulo h 16) 12) ((string-append "C" (toHexm (floor(/ h 16))))))
     ((= (modulo h 16) 13) ((string-append "D" (toHexm (floor(/ h 16))))))
     ((= (modulo h 16) 14) ((string-append "E" (toHexm (floor(/ h 16))))))
     ((= (modulo h 16) 15) ((string-append "F" (toHexm (floor(/ h 16))))))
     )

    (cond
     ((= h 1) "1")
     ((= h 2) "2")
     ((= h 3) "3")
     ((= h 4) "4")
     ((= h 5) "5")
     ((= h 6) "6")
     ((= h 7) "7")
     ((= h 8) "8")
     ((= h 9) "9")
     ((= h 10) "A")
     ((= h 11) "B")
     ((= h 12) "C")
     ((= h 13) "D")
     ((= h 14) "E")
     ((= h 15) "F")
     )
    )
)

(define (toHex h)
  (list->string (reverse (string->list (toHexm h))))
)

(define (main)
  (display(toHex 24))
)

(main)

Trying to take a base 10 and turn it into hex. This is giving me an error:

"procedure application: expected procedure, given: "81" (no arguments)"

This tells me nothing. I'm really new to scheme, so it could be an error in syntax, and this is as much as I know and can use for this problem. This code does work for the numbers under 15 so I assume it is related to the recursion in the numbers above 15. I appreciate any ideas or help you can give.

È stato utile?

Soluzione

There are extra () surrounding the code after each condition in the first cond, those are causing the error being reported. In Lisp, a pair of () means function application, and they're not to be used as if they were {} in other programming languages. Also notice that you forgot to consider the case where the number is zero! Try this:

(define (toHexm h)
  (if (> h 15)
      (cond
        ; missing case
        ((= (modulo h 16) 0) (string-append "0" (toHexm (floor(/ h 16))))) 
        ((= (modulo h 16) 1) (string-append "1" (toHexm (floor(/ h 16)))))
        ((= (modulo h 16) 2) (string-append "2" (toHexm (floor(/ h 16)))))
        ((= (modulo h 16) 3) (string-append "3" (toHexm (floor(/ h 16)))))
        ((= (modulo h 16) 4) (string-append "4" (toHexm (floor(/ h 16)))))
        ((= (modulo h 16) 5) (string-append "5" (toHexm (floor(/ h 16)))))
        ((= (modulo h 16) 6) (string-append "6" (toHexm (floor(/ h 16)))))
        ((= (modulo h 16) 7) (string-append "7" (toHexm (floor(/ h 16)))))
        ((= (modulo h 16) 8) (string-append "8" (toHexm (floor(/ h 16)))))
        ((= (modulo h 16) 9) (string-append "9" (toHexm (floor(/ h 16)))))
        ((= (modulo h 16) 10) (string-append "A" (toHexm (floor(/ h 16)))))
        ((= (modulo h 16) 11) (string-append "B" (toHexm (floor(/ h 16)))))
        ((= (modulo h 16) 12) (string-append "C" (toHexm (floor(/ h 16)))))
        ((= (modulo h 16) 13) (string-append "D" (toHexm (floor(/ h 16)))))
        ((= (modulo h 16) 14) (string-append "E" (toHexm (floor(/ h 16)))))
        ((= (modulo h 16) 15) (string-append "F" (toHexm (floor(/ h 16))))))
      (cond
        ; missing case
        ((= h 0)  "0")
        ((= h 1)  "1")
        ((= h 2)  "2")
        ((= h 3)  "3")
        ((= h 4)  "4")
        ((= h 5)  "5")
        ((= h 6)  "6")
        ((= h 7)  "7")
        ((= h 8)  "8")
        ((= h 9)  "9")
        ((= h 10) "A")
        ((= h 11) "B")
        ((= h 12) "C")
        ((= h 13) "D")
        ((= h 14) "E")
        ((= h 15) "F"))))

With a bit of fiddling the code can be further simplified, and we can get rid of the (list->string (reverse (string->list part - that's just a symptom that the recursion wasn't correctly formulated:

(define (toHexm h)
  (cond ((= h 0)  "0")
        ((= h 1)  "1")
        ((= h 2)  "2")
        ((= h 3)  "3")
        ((= h 4)  "4")
        ((= h 5)  "5")
        ((= h 6)  "6")
        ((= h 7)  "7")
        ((= h 8)  "8")
        ((= h 9)  "9")
        ((= h 10) "A")
        ((= h 11) "B")
        ((= h 12) "C")
        ((= h 13) "D")
        ((= h 14) "E")
        ((= h 15) "F")
        (else (error "invalid number: " h))))

(define (toHex h)
  (if (< h 16)
      (toHexm h)
      (string-append (toHex  (quotient  h 16))
                     (toHexm (remainder h 16)))))

Or as a tail-recursive procedure:

(define (toHex h)
  (let loop ((n h) (acc ""))
    (if (< n 16)
        (string-append (toHexm n) acc)
        (loop (quotient n 16)
              (string-append (toHexm (remainder n 16)) acc)))))

Either way it works as expected:

(toHex 4)
=> "4"
(toHex 10)
=> "A"
(toHex 15)
=> "F"
(toHex 24)
=> "18"
(toHex 32)
=> "20"
(toHex 250)
=> "FA"
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top