Skip to content

Commit 582ccbd

Browse files
Copilotjackfirth
andcommitted
Complete implementation of fuse-map-with-for rule
Co-authored-by: jackfirth <[email protected]>
1 parent 98962bc commit 582ccbd

File tree

3 files changed

+22
-22
lines changed

3 files changed

+22
-22
lines changed

default-recommendations.rkt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
resyntax/default-recommendations/let-replacement/match-let-replacement
3232
resyntax/default-recommendations/list-shortcuts
3333
resyntax/default-recommendations/loops/for-loop-shortcuts
34+
resyntax/default-recommendations/loops/fuse-map-with-for
3435
resyntax/default-recommendations/loops/list-loopification
3536
resyntax/default-recommendations/loops/named-let-loopification
3637
resyntax/default-recommendations/match-shortcuts
@@ -73,6 +74,7 @@
7374
resyntax/default-recommendations/let-replacement/match-let-replacement
7475
resyntax/default-recommendations/list-shortcuts
7576
resyntax/default-recommendations/loops/for-loop-shortcuts
77+
resyntax/default-recommendations/loops/fuse-map-with-for
7678
resyntax/default-recommendations/loops/list-loopification
7779
resyntax/default-recommendations/loops/named-let-loopification
7880
resyntax/default-recommendations/match-shortcuts
@@ -104,6 +106,7 @@
104106
exception-suggestions
105107
file-io-suggestions
106108
for-loop-shortcuts
109+
fuse-map-with-for
107110
function-definition-shortcuts
108111
function-shortcuts
109112
hash-shortcuts

default-recommendations/loops/fuse-map-with-for-test.rkt

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,6 @@ no-change-test: "map with short lambda but ys used elsewhere not refactorable"
4949
--------------------
5050

5151

52-
no-change-test: "map with non-short lambda not refactorable"
53-
--------------------
54-
(define (f xs)
55-
(define ys (map (λ (x) (+ x 1)) xs))
56-
(for ([y (in-list ys)])
57-
(displayln y)))
58-
--------------------
59-
60-
6152
test: "map with lambda that has multiple body forms is refactorable"
6253
--------------------
6354
(define (f xs g)

default-recommendations/loops/fuse-map-with-for.rkt

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,33 @@
1919
;@----------------------------------------------------------------------------------------------------
2020

2121

22-
;; A short lambda suitable for fusing with a for loop. Needs both single-attribute and
23-
;; multi-attribute versions of the body for different template contexts.
22+
;; A short lambda suitable for fusing with a for loop. For multi-body lambdas, we need to
23+
;; separate the prefix forms (all but last) from the result form (the last).
2424
(define-syntax-class fuseable-map-lambda
25-
#:attributes (x single-body [multi-body 1])
25+
#:attributes (x single-body [multi-body 1] [prefix-forms 1] result-form)
2626

27-
;; Lambdas with let expressions that can be refactored - must come first as it's most specific
27+
;; Lambdas with let expressions that can be refactored
2828
(pattern
2929
(_:lambda-by-any-name (x:id)
3030
original-body:body-with-refactorable-let-expression)
31-
#:attr [multi-body 1] (attribute original-body.refactored)
32-
;; For single body, we need to wrap multiple forms in a begin
31+
#:with (multi-body ...) #'(original-body.refactored ...)
32+
#:attr [prefix-forms 1] (attribute original-body.refactored)
33+
#:attr result-form #'(begin)
3334
#:attr single-body #'(begin original-body.refactored ...))
3435

3536
;; Lambdas with multiple body forms (two or more)
36-
(pattern (_:lambda-by-any-name (x:id) first-form second-form rest-form ...)
37-
#:attr [multi-body 1] (cons (attribute first-form)
38-
(cons (attribute second-form) (attribute rest-form)))
39-
#:attr single-body #'(begin first-form second-form rest-form ...))
37+
(pattern (_:lambda-by-any-name (x:id) prefix-form ... last-form)
38+
#:when (not (null? (attribute prefix-form)))
39+
#:with (multi-body ...) #'(prefix-form ... last-form)
40+
#:attr [prefix-forms 1] (attribute prefix-form)
41+
#:attr result-form #'last-form
42+
#:attr single-body #'(begin prefix-form ... last-form))
4043

4144
;; Short lambdas with a single body form
4245
(pattern (_:lambda-by-any-name (x:id) only-form)
43-
#:attr [multi-body 1] (list (attribute only-form))
46+
#:with (multi-body ...) #'(only-form)
47+
#:attr [prefix-forms 1] '()
48+
#:attr result-form #'only-form
4449
#:attr single-body #'only-form))
4550

4651

@@ -64,7 +69,7 @@
6469
;; Generate the refactored code - fuse as nested clauses
6570
(body-before ...
6671
(for-id ([function.x (in-list list-expr)]
67-
[y-var (in-list (function.multi-body ...))]
72+
[y-var (in-list function.single-body)]
6873
remaining-clause ...)
6974
for-body ...)
7075
body-after ...))
@@ -91,7 +96,8 @@
9196
;; Generate the refactored code - use internal definition
9297
(body-before ...
9398
(for-id ([function.x (in-list list-expr)])
94-
(define y-var function.single-body)
99+
function.prefix-forms ...
100+
(define y-var function.result-form)
95101
for-body ...)
96102
body-after ...))
97103

0 commit comments

Comments
 (0)