Skip to content

Commit cd4eb66

Browse files
authored
Add for-set!-to-for/fold rule (#470)
Closes #386.
1 parent c0d1b27 commit cd4eb66

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

default-recommendations/for-loop-shortcuts-test.rkt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,25 @@ test: "for/and with or guarding simple expression not refactorable"
324324
------------------------------
325325

326326

327+
test: "for with set! refactorable to for/fold"
328+
------------------------------
329+
(define (f)
330+
(define xs '())
331+
(for ([i (in-range 0 10)])
332+
(define j (* i 2))
333+
(set! xs (cons j xs)))
334+
(reverse xs))
335+
------------------------------
336+
------------------------------
337+
(define (f)
338+
(define xs
339+
(for/fold ([xs '()]) ([i (in-range 0 10)])
340+
(define j (* i 2))
341+
(cons j xs)))
342+
(reverse xs))
343+
------------------------------
344+
345+
327346
test: "for/fold building hash to for/hash"
328347
------------------------------
329348
(for/fold ([h (hash)])

default-recommendations/for-loop-shortcuts.rkt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,23 @@
266266
((~replacement loop-id.set-id #:original loop-id) clauses body ...))
267267

268268

269+
(define-definition-context-refactoring-rule for-set!-to-for/fold
270+
#:description "`for/fold` can be used instead of a mutating `for` loop"
271+
#:literals (for set!)
272+
(~seq body-before ...
273+
(define accum:id init-expr:expr)
274+
(for clauses for-body ... (set! accum2:id update-expr:expr))
275+
body-after ...)
276+
#:when (free-identifier=? (attribute accum) (attribute accum2))
277+
(body-before ...
278+
(define accum
279+
(for/fold ([accum init-expr])
280+
clauses
281+
for-body ...
282+
update-expr))
283+
body-after ...))
284+
285+
269286
(define-refactoring-rule for/fold-building-hash-to-for/hash
270287
#:description "This `for` loop is building a hash and can be simplified."
271288
#:literals (for/fold for*/fold hash make-immutable-hash hash-set)
@@ -518,6 +535,7 @@ return just that result."
518535
for/fold-with-conditional-body-to-unless-keyword
519536
for/fold-with-conditional-body-to-when-keyword
520537
for-each-to-for
538+
for-set!-to-for/fold
521539
hash-for-each-to-for
522540
list->set-to-for/set
523541
list->vector-to-for/vector

0 commit comments

Comments
 (0)