I have started working on my first racket function but there is a big problem.
(define (sequence low hide stride)
(letrec ([list-of-int null])
(define (f low hide stride)
(if (< low hide)
[(begin ((append (list low) list-of-int)
(f (+ low stride) hide stride)))]
[list-of-int]))
(f low hide stride)))
Can anybody help me with my racket understanding? In my mind it looks fine but doesn't work. I have found more simple solution in internet:
(define (sequence low high stride)
(if (> low high)
null
(cons low (sequence (+ low stride) high stride))))
I understand it but why my code doesn't work? Can anybody help me?
Oscars answer is really great) Thanks a lot dear friend.
First of all, this function already exists in Racket, and it's called range:
(range 1 11 1)
=> '(1 2 3 4 5 6 7 8 9 10)
Now, regarding your implementation you have to remember that list operations in Scheme do not modify lists in-place. In particular, this line is not doing what you imagine:
(append (list low) list-of-int)
Sure enough, append added a new element, but it returned a new list, and because you didn't store it as a variable or passed it as a parameter that modification was lost. Besides, it's better to use cons to build an output list, using append will result in a quadratic performance. Also, there's a mistake in here:
[(begin ((
See those double [( and (( there? they' re causing the "application: not a procedure" error being reported. In Scheme, surrounding an expression with () means function application - parentheses are not to be used for defining blocks of code, as you would use {} in other programming languages. A correct implementation from scratch follows, closer to what you had in mind and preserving the same behavior as range:
(define (sequence low high stride)
(define (f low cmp acc) ; lower bound, comparator and accumulator
(if (cmp high low) ; exit condition for base case
(reverse acc) ; reverse and return the accumulator
(f (+ low stride) ; advance lower bound
cmp ; pass the comparator
(cons low acc)))) ; build the list
(if (positive? stride) ; if the step is positive
(f low <= '()) ; initialize with <= comparator and '()
(f low >= '()))) ; else initialize with >= and '()
It works as expected:
(sequence 1 11 1)
=> '(1 2 3 4 5 6 7 8 9 10)
(sequence 1 12 2)
=> '(1 3 5 7 9 11)
(sequence 10 0 -1)
=> '(10 9 8 7 6 5 4 3 2 1)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With