Racket analyzer?

Am I on the right track for a Racket analyzer?

I’m looking at using GitHub - jackfirth/resyntax: A Racket refactoring engine, a Racket refactoring recommendations package that has been used on several Racket community repos to date.

resyntax analyze --file-path <file-path> prints out each rule, a rule description, the code in question, and then the recommended code edits. In the snippet below, the rules are let-to-define and nested-if-to-cond

resyntax analyze --file example.rkt
resyntax: --- analyzing code ---
resyntax: analyzing /Users/anagy/Documents/example.rkt
resyntax: --- displaying results ---
resyntax: /Users/anagy/Documents/example.rkt [let-to-define]


  Internal definitions are recommended instead of `let` expressions, to reduce nesting.


  3 (define (swap x y)
  4   (let ([t (unbox x)])
  5     (set-box! x (unbox y))
  6     (set-box! y t)))


  3 (define (swap x y)
  4   (define t (unbox x))
  5   (set-box! x (unbox y))
  6   (set-box! y t))


resyntax: /Users/anagy/Documents/example.rkt [nested-if-to-cond]


  This `if`-`else` chain can be converted to a `cond` expression.


  8 (if 'cond 'then (if 'cond2 'then2 'else))


  8  (cond
  9    ['cond 'then]
  10   ['cond2 'then2]
  11   [else 'else])

I’d pull out the rule name, description, and affected code, leaving behind the recommended edit. Each set can be passed as parameters to a generic Markdown file rather than mapping each rule to its own Markdown file in website/copy.

I can leave out the recommended code edits but use the rest to provide analyzer feedback. To avoid generating a Markdown file for each rule, I’d just pass everything as parameters to a single generic Markdown file.

2 Likes

Sounds good

Interesting. I have always thought that let should be used instead of internal define because the distinction between let, let* and letrec makes the intent clearer. But I see that the style guide says " favor define when feasible." So I learned something new today. Thanks!

When I tried it on some of my code, resyntax failed with a contract violation!

To update on this, I have been working with Jack Firth, the author of resyntax, to understand the problem. The files that made resyntax fail were in “dos” format, i.e., using “\r\n” as line terminators. I use a Mac and normally have no truck with dos files, but evidently the stubs that I downloaded were in that format and my editor (vim) kept them that way. Converting to “unix” format (“\n” only) makes the problem go away.

The problem with “\r\n”, as Jack discovered, is that while it is two characters, the read-syntax function treats it as if it were just one, which makes the source location come out wrong as far as resyntax is concerned, so that things go haywire when it tries to refer back to the original code.

The solution is to make resyntax aware that lines may have terminators of varying length. Jack says that he will come up with a fix, but in the meantime, if we want to use resyntax, we should make sure that files are converted to unix format before we analyze them.

Further update: Jack found a simpler fix and checked it in, so it should be clear sailing now. For those keeping score at home, reencode-input-port has a handy convert-newlines? parameter that gets rid of the troublesome carriage returns.

1 Like