Resyntax: A Macro-Powered Refactoring Tool

Some of you may already know this, but I've implemented a refactoring tool for Racket called Resyntax. It analyzes your code (must be written in #lang racket/base) and suggests ways you can improve it. Here's an example of the changes it made when I ran it over a real-world package. To use Resyntax, install it in installation scope (this is very important!) using raco pkg install --installation resyntax. Then you can run it at the command line. Here are some example commands:

  • Analyze a file and print suggestions in the terminal: resyntax analyze --file foo.rkt
  • Analyze multiple files: resyntax analyze --file foo.rkt --file bar.rkt
  • Fix a file: resyntax fix --file foo.rkt
  • Fix a directory: resyntax fix --directory path/to/some/dir
  • Fix a locally-installed package: resyntax fix --package mypackage (the package should be installed with --link option for this to work the way you expect)
8 Likes

Very nice! :clap:

I love this one (click on the header starting with github.com/jackfirth..., not on Run ...):

A little more room for refactoring :slight_smile:
(and ... (and ...) ...) -> (and ...)

Did it miss a let->define? Or is it because the internal definitions of the let may then be spliced? If the latter, then maybe suggest using (block (define ...)...)?

1 Like

The (and ... (and ...) ...) -> (and ...) case is normally refactored by Resyntax, but there's some logic to skip it for multiline ands so that this:

(and (long-expr)
     (and a b c d e))

doesn't become this:

(and (long-expr)
     a
     b
     c
     d
     e)

That logic is overly conservative though, and should be adjusted.

For that let->define case, syntax-case doesn't allow internal definitions. The better fix there is to replace syntax-case with syntax-parse.

2 Likes