Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions default-recommendations/syntax-shortcuts-test.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,18 @@ test: "making a symbol with format from a keyword can be simplified to format-sy
test: "making a symbol with format from a keyword syntax object can be simplified to format-symbol"
- (string->symbol (format "make-~a" (keyword->string (syntax-e #'#:foo))))
- (format-symbol "make-~a" #'#:foo)


test: "flattening nested syntax templates with apply append can be simplified"
--------------------
(require racket/syntax)
(define (f stx)
(with-syntax ([((a ...) ...) stx])
(apply append
(map syntax->list (syntax->list #'((a ...) ...))))))
====================
(require racket/syntax)
(define (f stx)
(with-syntax ([((a ...) ...) stx])
(syntax->list (syntax (a ... ...)))))
--------------------
25 changes: 24 additions & 1 deletion default-recommendations/syntax-shortcuts.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

(require racket/string
racket/syntax
racket/list
rebellion/private/static-name
resyntax/base
syntax/parse)
Expand Down Expand Up @@ -103,6 +104,28 @@
(format-symbol template (~replacement arg.simplified #:original arg) ...))


(define-refactoring-rule flatten-apply-append-syntax-template
#:description
"Flattening nested syntax templates with `apply append` and `map syntax->list` can be simplified\
by using a single `syntax->list` call on a flattened template."
#:literals (apply append map syntax->list syntax ...)

(apply append (map syntax->list (syntax->list (syntax ((inner ...) ...)))))

#:with flattened-template
(let* ([inner-attrs (attribute inner)]
; When matching ((inner ...) ...), the inner attribute contains the elements from
; within each nested list. If there's only one element, inner-attrs will be a single
; syntax object, otherwise it's a list. We need a list for appending the ellipses.
[inner-list (if (list? inner-attrs) inner-attrs (list inner-attrs))]
[ellipsis-sym (datum->syntax #'here '...)])
; Construct (inner-elements ... ...) by appending two ellipsis symbols
(datum->syntax #'here (append inner-list (make-list 2 ellipsis-sym))))

(syntax->list #'flattened-template))


(define-refactoring-suite syntax-shortcuts
#:rules (format-string-to-format-symbol
#:rules (flatten-apply-append-syntax-template
format-string-to-format-symbol
syntax-e-in-format-id-unnecessary))