Skip to content

Commit bb3ef8b

Browse files
authored
Restrict or-in-for/and refactoring to obviously useful cases (#359)
Closes #357. Now it only fires if the last clause uses `let`, since that probably means the `or` is just serving as a way to get some simple cases out of the way before the main logic of the loop body.
1 parent 0ef2abe commit bb3ef8b

File tree

2 files changed

+25
-15
lines changed

2 files changed

+25
-15
lines changed

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

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -242,22 +242,29 @@ test: "andmap to for/and"
242242
------------------------------
243243

244244

245-
test: "for/and with or to filter clause"
245+
test: "for/and with or guarding complex expression to filter clause"
246246
------------------------------
247-
(define some-list (list 3 5 14 10 6 5 2))
247+
(define some-list (list 3 "foo" 5 14 "bar" 10 6 "baz" 5 2))
248248
(for/and ([x (in-list some-list)])
249249
(or (number? x)
250-
(positive? x)
251-
(not (even? x))
252-
(< x 10)))
250+
(let ([l (string-length x)])
251+
(and (odd? l) (< l 10)))))
253252
------------------------------
254253
------------------------------
255-
(define some-list (list 3 5 14 10 6 5 2))
254+
(define some-list (list 3 "foo" 5 14 "bar" 10 6 "baz" 5 2))
256255
(for/and ([x (in-list some-list)]
257-
#:unless (number? x)
258-
#:unless (positive? x)
259-
#:when (even? x))
260-
(< x 10))
256+
#:unless (number? x))
257+
(define l (string-length x))
258+
(and (odd? l) (< l 10)))
259+
------------------------------
260+
261+
262+
test: "for/and with or guarding simple expression not refactorable"
263+
------------------------------
264+
(define some-list (list 3 "foo" 5 14 "bar" 10 6 "baz" 5 2))
265+
(for/and ([x (in-list some-list)])
266+
(or (number? x)
267+
(string? x)))
261268
------------------------------
262269

263270

default-recommendations/for-loop-shortcuts.rkt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -408,17 +408,20 @@ return just that result."
408408
true-branch))
409409

410410

411-
(define-refactoring-rule or-in-for/and-to-filter-clause
412-
#:description "The `or` expression in this `for` loop can be replaced by a filtering clause."
411+
(define-refactoring-rule or-let-in-for/and-to-filter-clause
412+
#:description
413+
"The `or` expression in this `for` loop can be replaced by a filtering clause, letting you use\
414+
`define` instead of `let` in the loop body."
413415
#:literals (for/and for*/and or)
414416
((~and loop-id (~or for/and for*/and))
415417
(~and original-clauses (clause ...))
416-
(~and original-body (or condition:condition-expression ...+ last-condition)))
418+
(~and original-body
419+
(or condition:condition-expression ...+ last-condition:refactorable-let-expression)))
417420
(loop-id
418421
(~replacement
419422
(clause ... (~@ (~if condition.negated? #:when #:unless) condition.base-condition) ...)
420423
#:original original-clauses)
421-
(~replacement last-condition #:original original-body)))
424+
(~@ . (~splicing-replacement (last-condition.refactored ...) #:original original-body))))
422425

423426

424427
(define-syntax-class apply-append-refactorable-for-loop
@@ -477,7 +480,7 @@ return just that result."
477480
nested-for-to-for*
478481
nested-for/and-to-for*/and
479482
nested-for/or-to-for*/or
480-
or-in-for/and-to-filter-clause
483+
or-let-in-for/and-to-filter-clause
481484
ormap-to-for/or
482485
unless-expression-in-for-loop-to-unless-keyword
483486
when-expression-in-for-loop-to-when-keyword))

0 commit comments

Comments
 (0)