From 597661fa4e90475843318d052859aedabbcff9f7 Mon Sep 17 00:00:00 2001 From: Alexis King Date: Tue, 3 Jan 2017 12:01:39 -0800 Subject: [PATCH] Make range from racket/list act like in-range when used with for --- .../scribblings/reference/pairs.scrbl | 9 ++++++- racket/collects/racket/list.rkt | 25 +++++++++++++++---- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/pkgs/racket-doc/scribblings/reference/pairs.scrbl b/pkgs/racket-doc/scribblings/reference/pairs.scrbl index c3a46df4ba..ab115961a1 100644 --- a/pkgs/racket-doc/scribblings/reference/pairs.scrbl +++ b/pkgs/racket-doc/scribblings/reference/pairs.scrbl @@ -1264,12 +1264,19 @@ predecessor until @racket[end] (excluded) is reached. If no starting point is provided, @racket[0] is used. If no @racket[step] argument is provided, @racket[1] is used. +Like @racket[in-range], a @racket[range] application can provide better +performance when it appears directly in a @racket[for] clause. + @mz-examples[#:eval list-eval (range 10) (range 10 20) (range 20 40 2) (range 20 10 -1) - (range 10 15 1.5)]} + (range 10 15 1.5)] + +@history[#:changed "6.7.0.4" + @elem{Adjusted to cooperate with @racket[for] in the same + way that @racket[in-range] does.}]} @defproc[(append-map [proc procedure?] [lst list?] ...+) diff --git a/racket/collects/racket/list.rkt b/racket/collects/racket/list.rkt index e23c526c91..eefd263433 100644 --- a/racket/collects/racket/list.rkt +++ b/racket/collects/racket/list.rkt @@ -61,6 +61,8 @@ remf remf*) +(require (for-syntax racket/base)) + (define (first x) (if (and (pair? x) (list? x)) (car x) @@ -561,11 +563,24 @@ (if (pred x) (loop l (cons x i) o) (loop l i (cons x o))))))) ;; similar to in-range, but returns a list -(define range - (case-lambda - [(end) (for/list ([i (in-range end)]) i)] - [(start end) (for/list ([i (in-range start end)]) i)] - [(start end step) (for/list ([i (in-range start end step)]) i)])) +(define range-proc + (let () + ; make sure range has the right runtime name + (define range + (case-lambda + [(end) (for/list ([i (in-range end)]) i)] + [(start end) (for/list ([i (in-range start end)]) i)] + [(start end step) (for/list ([i (in-range start end step)]) i)])) + range)) + +(define-sequence-syntax range + (λ () #'range-proc) + (λ (stx) + (syntax-case stx () + [[(n) (_ end)] #'[(n) (in-range end)]] + [[(n) (_ start end)] #'[(n) (in-range start end)]] + [[(n) (_ start end step)] #'[(n) (in-range start end step)]] + [[ids range-expr] #'[ids (#%expression range-expr)]]))) (define append-map (case-lambda [(f l) (apply append (map f l))]