pythonのrangeをschemeで

http://d.hatena.ne.jp/jdg/20100323/1269346849
どうしてたくさんのerror処理が入っているのかよく分からないのですが、単純にpythonのrangeをschemeに直すとこのような感じになるのではないでしょうか?

(define (step$ n) (lambda (x) (+ n x)))

(define (range start end . args)
  (let1 step (if (null? args) (step$ 1) (apply step$ args))
    (let rec ((i start))
      (if (>= i end) '() (cons i (rec (step i)))))))

gaucheならオプショナル引数*1が使えるので以下のようにもかけます。

(define (range start end :optional (n 1))
  (let1 step (step$ n)
    (let rec ((i start))
      (if (>= i end) '() (cons i (rec (step i)))))))

;; (for-each print (range 1 20))
;; (for-each print (range 1 20 3))

追記

そういえば、上のrangeは(range 100 1 -5)などには対応してませんね。コメントで指摘されて気づきました。

(define (range start end :optional (n 1))
  (let ((step (step$ n))
	(end? (if (> end start) >= <=)))
    (let rec ((i start))
      (if (end? i end) '() (cons i (rec (step i)))))))

そうそう、id:naotoakiyamaさんがコメントしてくれましたが、通常はsrfi-1のiotaを使います。rangeみたいな処理を書くときは。

*1:キーワード引数も使える