Reputation: 139
The goal is to check if a non-negative number's digits are in increasing order.
Here is my code:
(define (in-order-iter num)
(define (aux num-left result-so-far)
(cond ((equal? result-so-far #f) #f)
((< num-left 10) result-so-far)
((aux (quotient num-left 10) (< (modulo (quotient num-left 10) 10)(modulo num-left 10))))))
(aux num #t))
(in-order-iter 321)
The worst part is, when I decide to use (display result-so-far)
, I get the answer I want (which is #f
), but my function won't return it. If I decide to use (in-order-iter 123)
, it does return #t
.
When I test
(< (modulo (quotient 321 10) 10)(modulo 321 10)))
alone, it does return #f
, so it should change result-so-far
to #f
.
Why is this happening to me?!
Edit: By the way, I can do this function recursively and it works:
(define (in-order-recur num)
(if (> num 10)
(if (< (modulo (quotient num 10) 10) (modulo num 10))
(in-order-recur (quotient num 10))
#f)
#t))
(in-order-recur 100000)
Upvotes: 1
Views: 432
Reputation: 48745
You should use an else
clause as the last cond
term:
(define (in-order-iter num)
(define (aux num-left result-so-far)
(cond ((equal? result-so-far #f) #f)
((< num-left 10) result-so-far)
(else (aux (quotient num-left 10)
(< (modulo (quotient num-left 10) 10)
(modulo num-left 10))))))
(aux num #t))
So what happens when you don't is that the #f
becomes the predicate and since it is false it will go to the next term. Since you don't have any more terms it is up to the implementation to decide what should be the result of the cond
. From R6RS the suggestion is the "unspecified value". Eg. Racket will result in #<void>
which by default doesn't get printed. In reality though the implementation might do something like this:
(define (in-order-iter num)
(define (aux num-left result-so-far)
(cond ((equal? result-so-far #f) #f)
((< num-left 10) result-so-far)
((aux (quotient num-left 10)
(< (modulo (quotient num-left 10) 10)
(modulo num-left 10))))
(else "BaNaNa")))
(aux num #t))
Relying on what is returned as value, Eg. MIT Scheme returns some useful values, will lock you in to a specific dialect and not be portable.
If the value were to be true from the base case then the default case would then be #t
. Then since the term doesn't have a consequence part the #t
is the returned value.
Upvotes: 1