Skip to content

Commit 9f0aa04

Browse files
authored
Add list-selectors-to-take-and-drop (#444)
1 parent eff1e2b commit 9f0aa04

File tree

2 files changed

+131
-2
lines changed

2 files changed

+131
-2
lines changed

default-recommendations/list-shortcuts-test.rkt

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,3 +192,57 @@ test: "build-list with const refactorable to make-list"
192192
racket/list)
193193
(make-list 5 42)
194194
------------------------------
195+
196+
197+
test: "list of contiguous selections to take and drop"
198+
------------------------------
199+
(require racket/list)
200+
(define vs (list 'foo 'bar 'baz 'blah 'zorp 'zoog 'karp))
201+
(list (list-ref vs 2) (list-ref vs 3) (list-ref vs 4))
202+
------------------------------
203+
------------------------------
204+
(require racket/list)
205+
(define vs (list 'foo 'bar 'baz 'blah 'zorp 'zoog 'karp))
206+
(list (third vs) (fourth vs) (fifth vs))
207+
------------------------------
208+
------------------------------
209+
(require racket/list)
210+
(define vs (list 'foo 'bar 'baz 'blah 'zorp 'zoog 'karp))
211+
(list (caddr vs) (cadddr vs) (list-ref vs 4))
212+
------------------------------
213+
------------------------------
214+
(require racket/list)
215+
(define vs (list 'foo 'bar 'baz 'blah 'zorp 'zoog 'karp))
216+
(take (drop vs 2) 3)
217+
------------------------------
218+
219+
220+
test: "list of contiguous selections starting at first element to take"
221+
------------------------------
222+
(require racket/list)
223+
(define vs (list 'foo 'bar 'baz 'blah 'zorp 'zoog 'karp))
224+
(list (list-ref vs 0) (list-ref vs 1) (list-ref vs 2))
225+
------------------------------
226+
------------------------------
227+
(require racket/list)
228+
(define vs (list 'foo 'bar 'baz 'blah 'zorp 'zoog 'karp))
229+
(list (first vs) (second vs) (third vs))
230+
------------------------------
231+
------------------------------
232+
(require racket/list)
233+
(define vs (list 'foo 'bar 'baz 'blah 'zorp 'zoog 'karp))
234+
(list (car vs) (cadr vs) (caddr vs))
235+
------------------------------
236+
------------------------------
237+
(require racket/list)
238+
(define vs (list 'foo 'bar 'baz 'blah 'zorp 'zoog 'karp))
239+
(take vs 3)
240+
------------------------------
241+
242+
243+
test: "list of only two contiguous selections not refactorable to take and drop"
244+
------------------------------
245+
(require racket/list)
246+
(define vs (list 'foo 'bar 'baz 'blah 'zorp 'zoog 'karp))
247+
(list (list-ref vs 2) (list-ref vs 3))
248+
------------------------------

default-recommendations/list-shortcuts.rkt

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@
1010

1111

1212
(require (for-syntax racket/base)
13+
guard
1314
racket/function
1415
racket/list
16+
racket/sequence
1517
racket/set
16-
rebellion/private/static-name
1718
resyntax/base
1819
resyntax/default-recommendations/private/lambda-by-any-name
1920
resyntax/default-recommendations/private/literal-constant
2021
resyntax/default-recommendations/private/syntax-identifier-sets
21-
resyntax/private/syntax-neighbors
2222
syntax/parse)
2323

2424

@@ -140,6 +140,80 @@
140140
(make-list count elem))
141141

142142

143+
(define/guard (all-free-identifier=? ids)
144+
(guard-match (cons first-id remaining-ids) (sequence->list ids) #:else #false)
145+
(for/and ([id (in-list remaining-ids)])
146+
(free-identifier=? first-id id)))
147+
148+
149+
(define/guard (contiguous-increasing-integer-series? ints)
150+
(define int-list (sequence->list ints))
151+
(guard (not (empty? int-list)) #:else #false)
152+
(for/and ([previous (in-list int-list)]
153+
[next (in-list (rest int-list))])
154+
(equal? (add1 previous) next)))
155+
156+
157+
(define-syntax-class list-selection-expression
158+
#:attributes (target-list-id index)
159+
#:literals (list-ref
160+
first
161+
second
162+
third
163+
fourth
164+
fifth
165+
sixth
166+
seventh
167+
eighth
168+
ninth
169+
tenth
170+
car
171+
cadr
172+
caddr
173+
cadddr)
174+
175+
(pattern (list-ref target-list-id:id index-stx:nat) #:attr index (syntax-e #'index-stx))
176+
(pattern (first target-list-id:id) #:attr index 0)
177+
(pattern (second target-list-id:id) #:attr index 1)
178+
(pattern (third target-list-id:id) #:attr index 2)
179+
(pattern (fourth target-list-id:id) #:attr index 3)
180+
(pattern (fifth target-list-id:id) #:attr index 4)
181+
(pattern (sixth target-list-id:id) #:attr index 5)
182+
(pattern (seventh target-list-id:id) #:attr index 6)
183+
(pattern (eighth target-list-id:id) #:attr index 7)
184+
(pattern (ninth target-list-id:id) #:attr index 8)
185+
(pattern (tenth target-list-id:id) #:attr index 9)
186+
(pattern (car target-list-id:id) #:attr index 0)
187+
(pattern (cadr target-list-id:id) #:attr index 1)
188+
(pattern (caddr target-list-id:id) #:attr index 2)
189+
(pattern (cadddr target-list-id:id) #:attr index 3))
190+
191+
192+
(define-refactoring-rule list-selectors-to-take-and-drop
193+
#:description
194+
"This list expression is constructing a sublist of a larger list, which can be expressed more\
195+
clearly with `take` and `drop`."
196+
#:literals (list)
197+
198+
(list selection:list-selection-expression ...)
199+
200+
#:when (>= (length (attribute selection)) 3)
201+
202+
#:when (all-free-identifier=? (attribute selection.target-list-id))
203+
#:with target-list-id (first (attribute selection.target-list-id))
204+
205+
#:when (contiguous-increasing-integer-series? (attribute selection.index))
206+
#:do [(define first-index (first (attribute selection.index)))
207+
(define last-index (last (attribute selection.index)))]
208+
209+
#:with target-list-with-prefix-dropped
210+
(if (zero? first-index) #'target-list-id #`(drop target-list-id #,first-index))
211+
212+
#:with amount-to-take (- (add1 last-index) first-index)
213+
214+
(take target-list-with-prefix-dropped amount-to-take))
215+
216+
143217
(define-refactoring-suite list-shortcuts
144218
#:rules (append-single-list-to-single-list
145219
append*-and-map-to-append-map
@@ -150,6 +224,7 @@
150224
filter-to-remv*
151225
first-reverse-to-last
152226
ignored-map-to-for-each
227+
list-selectors-to-take-and-drop
153228
quasiquote-to-append
154229
quasiquote-to-list
155230
sort-with-keyed-comparator-to-sort-by-key))

0 commit comments

Comments
 (0)