Skip to content

Commit

Permalink
Add map-to-for refactoring (#254)
Browse files Browse the repository at this point in the history
This is similar to `for-each-to-for` but for refactoring `map` into `for/list`.
  • Loading branch information
jackfirth authored Aug 31, 2024
1 parent c714795 commit 02bce8b
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
99 changes: 99 additions & 0 deletions default-recommendations/for-loop-shortcuts-test.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,105 @@ header:
- #lang racket/base


test: "map with short single-form body not refactorable"
------------------------------
(define some-list (list 1 2 3))
(map (λ (x) (* x 2)) some-list)
------------------------------


test: "map with long single-form body to for/list"
------------------------------
(define some-list (list 1 2 3))
(map
(λ (a-very-very-very-long-variable-name-thats-so-very-long)
(* a-very-very-very-long-variable-name-thats-so-very-long 2))
some-list)
------------------------------
------------------------------
(define some-list (list 1 2 3))
(for/list ([a-very-very-very-long-variable-name-thats-so-very-long (in-list some-list)])
(* a-very-very-very-long-variable-name-thats-so-very-long 2))
------------------------------


test: "map with multiple body forms to for/list"
------------------------------
(define some-list (list 1 2 3))
(map
(λ (x)
(define y (* x 2))
(+ x y))
some-list)
------------------------------
------------------------------
(define some-list (list 1 2 3))
(for/list ([x (in-list some-list)])
(define y (* x 2))
(+ x y))
------------------------------


test: "map with let expression to for/list with definitions"
------------------------------
(define some-list (list 1 2 3))
(map (λ (x) (let ([y 1]) (+ x y))) some-list)
------------------------------
------------------------------
(define some-list (list 1 2 3))
(for/list ([x (in-list some-list)])
(define y 1)
(+ x y))
------------------------------


test: "map range to for/list"
------------------------------
(require racket/list)
(map
(λ (x)
(define y 1)
(+ x y))
(range 0 10))
------------------------------
------------------------------
(require racket/list)
(for/list ([x (in-range 0 10)])
(define y 1)
(+ x y))
------------------------------


test: "map string->list to for/list in-string"
------------------------------
(map
(λ (c)
(displayln c)
(char-upcase c))
(string->list "hello"))
------------------------------
------------------------------
(for/list ([c (in-string "hello")])
(displayln c)
(char-upcase c))
------------------------------


test: "map bytes->list to for/list in-bytes"
------------------------------
(map
(λ (b)
(displayln b)
(* b 2))
(bytes->list #"hello"))
------------------------------
------------------------------
(for/list ([b (in-bytes #"hello")])
(displayln b)
(* b 2))
------------------------------


test: "for-each with short single-form body not refactorable"
------------------------------
(define some-list (list 1 2 3))
Expand Down
10 changes: 10 additions & 0 deletions default-recommendations/for-loop-shortcuts.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,15 @@
#:with (body ...) #'(only-body)))


(define-refactoring-rule map-to-for
#:description "This `map` operation can be replaced with a `for/list` loop."
#:literals (map)
[(map function:worthwhile-loop-body-function loop:for-clause-convertible-list-expression)
((~if loop.flat? for/list for*/list)
(loop.leading-clause ... [function.x loop.trailing-expression])
function.body ...)])


(define-refactoring-rule for-each-to-for
#:description "This `for-each` operation can be replaced with a `for` loop."
#:literals (for-each)
Expand Down Expand Up @@ -303,6 +312,7 @@
for-each-to-for
list->set-to-for/set
list->vector-to-for/vector
map-to-for
named-let-loop-to-for/first-in-vector
nested-for-to-for*
or-in-for/and-to-filter-clause
Expand Down

0 comments on commit 02bce8b

Please sign in to comment.