Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Racket simple sequence of int generator function

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.

like image 951
Роман Иванов Avatar asked May 06 '26 01:05

Роман Иванов


1 Answers

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)
like image 175
Óscar López Avatar answered May 09 '26 05:05

Óscar López



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!