schemerangeracket

how to redefine the function "range" in Racket/Scheme?


i'm trying redefine the function "range" in Racket.

(define (my-range a b)
  (if (> a b)
      null
      (cons a (my-range (+ 1 a) b))))

;; Test

(my-range 2 5)

;; -> (cons 2 (cons 3 (cons 4 (cons 5 empty))))

Now I want to extend my-range as follows:

(define (my-range a b step) ...)

e.g. (my-range 2 6 1) --> (list 2 3 4 5)

The first number is a and each successive element is generated by adding step to the previous element. The sequence stops before an element that would be greater or equal to b. How can I do this?


Solution

  • From the comments I guess you already found the solution. For completeness' sake, here it is:

    (define (my-range a b step)
      (if (>= a b)
          null
          (cons a (my-range (+ step a) b step))))
    

    In fact, this procedure is rather common and it can be expressed in several ways. As @dyoo has pointed, range is a standard procedure:

    (define (my-range a b step)
      (range a b step))
    

    Also, in terms of build-list, another standard Racket procedure:

    (define (my-range a b step)
      (build-list (ceiling (/ (- b a) step))
                  (lambda (x) (+ a (* step x)))))
    

    Or using streams:

    (define (my-range a b step)
      (stream->list (in-range a b step)))