Skip to content

Move the user-friendly, non-keyword define to here#18

Open
jesboat wants to merge 2 commits intoracket:masterfrom
jesboat:pr-move-define-to-here
Open

Move the user-friendly, non-keyword define to here#18
jesboat wants to merge 2 commits intoracket:masterfrom
jesboat:pr-move-define-to-here

Conversation

@jesboat
Copy link
Contributor

@jesboat jesboat commented Mar 7, 2026

Commit log

mzscheme: use relative paths for package-local requires (easy)

So that editing the files uses the versions of the files next to the files being edited instead of the ones from the running Racket

mzscheme: define our own define, define-syntax, define-for-syntax

Previously, we imported the non-keyword versions of those macros from racket/private/define.rkt in the main repo (via a bridge module.)

This isn't ideal, though, because it means racket/private/define.rkt attempts to serve two purposes: being a user-suitable define and being low-level enough to finish implementing racket/base before the final (keyword) defines are supported. These purposes are in tension. Being user-suitable means it wants excellent error messages which means it wants to continue using the full machinery of normalize-definition, a good chunk of which is dedicated to producing the best error messages. Being low-level means it wants to be implemented using more low-level techniques, ideally in pure #%kernel which means it does not want to replicate that machinery, and, in practice, internal chunks of the racket/base implementation don't need perfect error messages. (For example, it's perfectly fine if duplicate argument names are reported in terms of the underling lambda form, or if defines with multiple errors don't report the leftmost one.)

By splitting those two purposes into a full-featured define with great error messages that can be implemented using complex features like normalize-definition, and a full-featured define which has poorer error messages but a simple pure-#%kernel implementation, we can serve both those purposes better. And, since the former is only used here, it should be defined here and not in racket/private.

Testing: ran DrRacket for a few days. Also code review, in particular noting
that the implementation added here is a direct copy-paste from
https://github.com/racket/racket/blob/a1dd05117d2abe8a9cc24fed82f8cd4f5b835d8d/racket/collects/racket/private/define.rkt
with the only changes being using racket/base instead of "kernel plus
various intermediate syntaxes" and the public export of normalize-definition
https://github.com/racket/racket/blob/a1dd05117d2abe8a9cc24fed82f8cd4f5b835d8d/racket/collects/syntax/define.rkt
instead of the private one.

This is a backwards-compatible change.

jesboat added 2 commits March 6, 2026 09:50
So that editing the files uses the versions of the files next to
the files being edited instead of the ones from the running Racket
Previously, we imported the non-keyword versions of those macros from
`racket/private/define.rkt` in the main repo (via a bridge module.)

This isn't ideal, though, because it means `racket/private/define.rkt` attempts
to serve two purposes: being a user-suitable define and being low-level enough
to finish implementing racket/base before the final (keyword) defines are
supported. These purposes are in tension. Being user-suitable means it wants
excellent error messages which means it wants to continue using the full
machinery of `normalize-definition`, a good chunk of which is dedicated to
producing the best error messages. Being low-level means it wants to be
implemented using more low-level techniques, ideally in pure `#%kernel`
which means it does not want to replicate that machinery, and, in practice,
internal chunks of the racket/base implementation don't need perfect error
messages. (For example, it's perfectly fine if duplicate argument names are
reported in terms of the underling lambda form, or if defines with multiple
errors don't report the leftmost one.)

By splitting those two purposes into a full-featured define with great error
messages that can be implemented using complex features like normalize-definition,
and a full-featured define which has poorer error messages but a simple
pure-`#%kernel` implementation, we can serve both those purposes better. And,
since the former is only used here, it should be defined here and not in
racket/private.

Testing: ran DrRacket for a few days. Also code review, in particular noting
that the implementation added here is a direct copy-paste from
https://github.com/racket/racket/blob/a1dd05117d2abe8a9cc24fed82f8cd4f5b835d8d/racket/collects/racket/private/define.rkt
with the only changes being using racket/base instead of "kernel plus
various intermediate syntaxes" and the public export of normalize-definition
https://github.com/racket/racket/blob/a1dd05117d2abe8a9cc24fed82f8cd4f5b835d8d/racket/collects/syntax/define.rkt
instead of the private one.

This is a backwards-compatible change.
@samth
Copy link
Member

samth commented Mar 8, 2026

This is an excellent idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants