jackfirth / jackfirth/resyntax
`define` vs `define/private` inside `class`
Nobody has claimed this yet.
- Dominant language
- Racket
- Stars
- 70
- Forks
- 11
- PR merge metrics
- No merged PRs in 30d
Description
An easy to overlook error is when folks write define in a class body to define a function, using per-instance storage instead of per-class storage. It would be great if resyntax offered to fix this; there have, historically, been many of these bugs in the framework and in drracket; it is really hard to see them (especially when you're looking at a giant class; you kind of forget that you're in a class at all!).
For example, this is bad:
(define conan%
(class object%
(define (kick-soccer-ball) ...)
(define (dart-mori-and-reveal-culprit) ...)
(super-new)))
as each object will have a slot for kick-soccer-ball and dart-mori and instead it should have been:
(define conan%
(class object%
(define/private (kick-soccer-ball) ...)
(define/private (dart-mori-and-reveal-culprit) ...)
(super-new)))
The is a subtle point, however, as sometimes private fields are bound to functions intentionally as they might be mutated. Even more subtle, sometimes the functions that are on private fields are used with the framework preference library to cause preference callbacks to be garbage collected when an object is itself no longer reachable. The field font-size-callback in drracket/private/tooltip is an example.
I think a reasonable rule would be to suggest changing define to define/private in the body of a class when the field is immediately a lambda (or (define (f x) ...) notation was used) and all occurrences of the defined variable appear only in the function position of an application. That would avoid having resyntax make incorrect suggestions in the example in the previous paragraph (and other, similar situations).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing resyntax's class-body refactoring and static-analysis entry points; the issue does not name an implementation file or test. Use the class examples and the proposed function-position occurrence rule as the behavioral specification, and compare the drracket/private/tooltip font-size-callback example to ensure intentional mutable callbacks are not suggested for rewriting.
Written by the indexing model from the issue text.
Assessment
- Domain
- devtools, tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100