Skip to content

Cleaning up racket/private dependencies - #15

Merged
mflatt merged 4 commits into
racket:masterfrom
jesboat:something-about-racket-private
Feb 17, 2026
Merged

Cleaning up racket/private dependencies#15
mflatt merged 4 commits into
racket:masterfrom
jesboat:something-about-racket-private

Conversation

@jesboat

@jesboat jesboat commented Feb 8, 2026

Copy link
Copy Markdown
Contributor

This PR is part of an effort to clarify what in racket/private is intended to be used (or is used) by other first-party packages. The overall plan is described in racket/racket#5425; this is the changes to compatability-lib.

Note that compatability-lib still has dependencies on racket/private/* modules-- but none of them are also dependencies of racket/base, and all of them are properly documented in racket/racket#5425.

There are four conceptual changes, each of which is in its own commit, but I think it's best to review as a single unified PR. The descriptions and test plan is:

Commits

Use an explicit list of provided identifiers in mzscheme/main.rkt

Previously, it was a conglomeration of explicit IDs, various all-froms from various racket (sometimes private) racket modules, and some all-from-excepts. This was far from ideal. It prevents those modules from adding or removing provided identifiers without a synchronized change in mzscheme, which lives in a different repo.

In contrast, the list of identifiers provided by mzscheme will probably rarely, if ever, change; the whole point is to preserve compatibility with existing code. Listing the provides explicitly is ugly, but much less error-prone.

Revamp mzscheme/main.rkt require list

Previously, it was a conglomeration of various racket/* modules, some nominally private, many used in the construction of racket/base. This is undesirable for reasons described in the previous commit. Instead, we can replace it almost entirely with public exports from racket/base, racket/tcp, racket/udp, and racket/promise. Only 6 imports cannot be replaced with public exports; they're handled in the next commit.

Stop using racket/private/* dependencies of racket/base, part 1

In mzscheme/priavte/*.rkt, there are some uses of some of various
standard Scheme-ey macros. Previously, those were being imported
directly from various racket/private/* modules which were chunks
of racket/base. Import them from racket/base instead.

Stop using racket/private/* dependencies of racket/base, part 2

In mzscheme/main.rkt, use the for-compatability-lib module created in
racket/racket#5425

Testing

Using
https://gist.github.com/jesboat/6c474b9fc78b59ec2a6b6c8b975def80
to print the provides of mzscheme/main.rkt along with their original bindings, and it shows the same before and after. Reviewing the other files is done manually.

Previously, it was a conglomeration of explicit IDs, various `all-from`s from
various `racket` (sometimes private) racket modules, and some
`all-from-except`s. This was far from ideal. It prevents those modules from
adding or removing provided identifiers without a synchronized change in
`mzscheme`, which lives in a different repo.

In contrast, the list of identifiers provided by `mzscheme` will probably rarely,
if ever, change; the whole point is to preserve compatibility with existing code.
Listing the provides explicitly is ugly, but much less error-prone.

Test:

Print the module's provided identifiers along with the source bindings using
https://gist.github.com/jesboat/6c474b9fc78b59ec2a6b6c8b975def80
It's the same before and after.
Previously, it was a conglomeration of various `racket/*` modules, some
nominally private, many used in the construction of racket/base. This is
undesirable for reasons described in the previous commit. Instead, we can
replace it almost entirely with public exports from `racket/base`,
`racket/tcp`, `racket/udp`, and `racket/promise`. Only 6 imports cannot
be replaced with public exports; they're handled in the next commit.

Test Plan:

Print the module's provided identifiers along with the source bindings using
https://gist.github.com/jesboat/6c474b9fc78b59ec2a6b6c8b975def80
It's the same before and after.
In `mzscheme/priavte/*.rkt`, there are some uses of some of various
standard Scheme-ey macros. Previously, those were being imported
directly from various `racket/private/*` modules which were chunks
of racket/base. Import them from `racket/base` instead.

Test:

Change was done interactively. The count of bound uses DrRacket shows for
each of the required modules adds up properly. Checking that the required
identifiers are compatible is manual.
In mzscheme/main.rkt, use the `for-compatability-lib` module created in
racket/racket#5425

Test:

Print the module's provided identifiers along with the source bindings using
https://gist.github.com/jesboat/6c474b9fc78b59ec2a6b6c8b975def80
It's the same before and after.
jesboat added a commit to jesboat/racket that referenced this pull request Feb 15, 2026
Previously, the module defined two structs:

1. Struct `struct:break-paramz` (defined with `make-struct-type` and,
confusingly, with reflexive name `break-parameterization`) used for
the break parameterization

2. Struct `break-parameterization` (defined with the only remaining use
of `-define-struct`) which is unused locally and not `provide`d anywhere.
This goes at least as far back as v3.99.0.2, git 39cedb6, svn r7706.

Remove the unused one, which will enable removing `-define-struct` once
racket/compatibility#15 is also merged
@mflatt

mflatt commented Feb 15, 2026

Copy link
Copy Markdown
Member

Reducing the use of private modules is a great improvement!

I'm less sure of the value of listing all exports explicitly, as far as i understand things now. At a minimum, it seems like the documentation would need a corresponding change, since it currently says "scheme/base but without this handful of things", and scheme/base says "racket/base but with these adjustments". I would be inclined to stick with the old way, but I can go along with this (as long as the documentation is updated) if others think it's better.

mflatt pushed a commit to racket/racket that referenced this pull request Feb 15, 2026
Previously, the module defined two structs:

1. Struct `struct:break-paramz` (defined with `make-struct-type` and,
confusingly, with reflexive name `break-parameterization`) used for
the break parameterization

2. Struct `break-parameterization` (defined with the only remaining use
of `-define-struct`) which is unused locally and not `provide`d anywhere.
This goes at least as far back as v3.99.0.2, git 39cedb6, svn r7706.

Remove the unused one, which will enable removing `-define-struct` once
racket/compatibility#15 is also merged
@jesboat

jesboat commented Feb 15, 2026

Copy link
Copy Markdown
Contributor Author

Hmm. We've got https://docs.racket-lang.org/mzscheme/index.html starting with "The mzscheme language provides nearly the same bindings as the mzscheme module of PLT Scheme version 372 and earlier.", but an implementation and docs which seem to define themselves by the difference between them and racket/base. I feel like there's an inherent tension there, with whether mzscheme is closer to "like PLT Scheme 372" or "scheme/base but with X changed".

I don't think it makes sense to have an implicit export list without an the imports also being implicit; for racket/base, that might be a bit obnoxious, but I can try prototyping it. I can think of a couple other options:

  1. Changing the docs to dynamically generate the list of excluded functions (this might take me a bit of time; my Scribble is quite rusty)
  2. Changing the docs to statically list the included functions
  3. Revise the docs to remove references to v372 (since, now that I'm considering it, I don't actually know how much else might have snuck in to mzscheme's exports since then.)

Thoughts?

@mflatt

mflatt commented Feb 15, 2026

Copy link
Copy Markdown
Member

I see. I was going more by "Omitted Forms and Functions", which I took to imply that everything else not replaced was included, but maybe that's not really what it says.

The combination of 2 and 3 (1 seems like overkill) sounds ok to me.

@jesboat

jesboat commented Feb 15, 2026

Copy link
Copy Markdown
Contributor Author

I see. I was going more by "Omitted Forms and Functions", which I took to imply that everything else not replaced was included, but maybe that's not really what it says.

Perhaps it was originally intended to mean that, but, as time has passed and racket/base grew but mzscheme continued to only require chunks of it, the list became more and more inaccurate? https://gist.github.com/jesboat/4205f5b1aa42f12ed2bb355e5cc87a0d is a rough list of things which are exported by racket/{base,tcp,udp,promise} but not re-exported by mzscheme and which the docs sorta imply should be there; and some of that list is definitely spurious and a lot of it is related to for and friends, but there's still probably 10-30 things which the docs miss. That's my hypothesis, anyway.

The combination of 2 and 3 (1 seems like overkill) sounds ok to me.

Ack.

@jesboat

jesboat commented Feb 15, 2026

Copy link
Copy Markdown
Contributor Author

Here's the delta between 372 (the binary build still runs fine!) and the current #lang mzscheme
https://gist.github.com/jesboat/7bb7a4127dc68ff8f8379f75435af13a

@jesboat

jesboat commented Feb 16, 2026

Copy link
Copy Markdown
Contributor Author
  1. Changing the docs to statically list the included functions
  2. Revise the docs to remove references to v372 (since, now that I'm considering it, I don't actually know how much else might have snuck in to mzscheme's exports since then.)

The combination of 2 and 3 (1 seems like overkill) sounds ok to me.

So, doing 2 is also turning out to be messier than anticipated, because mzscheme's been exporting most of #%kernel for a while, and there's a pile of stuff in #%kernel whose public documentation (and therefore where the mzscheme's scribblings would want to link) is spread out. There's the expected stuff in racket/{base,tcp,udp,promise}, but there's also:

  • keyword->immutable-string from racket/keyword
  • {mutable,immutable}-{bytes,string,box,vector,hash}? from racket/mutability
  • symbol->immutable-string) from racket/symbol
  • syntax-srcloc from racket/syntax-srcloc
  • various from racket/vector
  • various (roughly 15) kernel non-keyword variants which could be documented in https://docs.racket-lang.org/mzscheme/Old_Functions.html#%28def._%28%28lib._mzscheme%2Fmain..rkt%29._make-namespace%29%29 but aren't (e.g. chaperone-procedure, procedure->method, copy-file, directory-list, raise-syntax-error, syntax-serialize)
  • some variant of random and regexp-replace*
  • these, which appear documented nowhere: do-raise-syntax-error, interned-char?, list-pair?, prop:method-arity-error, true-object?

I'm tempted to suggest:

(a) Merge racket/racket#5425 to main repo.
(b) Then merge this roughly as-is before the doc changes are ready; this reduces the shims racket/racket#5406 would need to create and doesn't make the current docs any less accurate
(c) Work on the doc changes in parallel; eventually (estimate 1-3 weeks)

@mflatt
mflatt merged commit 7d3921b into racket:master Feb 17, 2026
jesboat added a commit to jesboat/racket--compatibility that referenced this pull request Feb 17, 2026
In the preceding commits (racket#15),
I consistently spelled "compatibility" wrong. Fix it.

Fixing the filename requires a cross-repo change (with this and
racket/racket#5434), so it'll be the second
cross-repo breaking change in ~3 hours, but it seems better to do it now than
wait until later or leave the misspelling there forever.

Sorry :(
mflatt pushed a commit that referenced this pull request Feb 17, 2026
In the preceding commits (#15),
I consistently spelled "compatibility" wrong. Fix it.

Fixing the filename requires a cross-repo change (with this and
racket/racket#5434), so it'll be the second
cross-repo breaking change in ~3 hours, but it seems better to do it now than
wait until later or leave the misspelling there forever.

Sorry :(
jesboat added a commit to jesboat/racket that referenced this pull request Feb 21, 2026
This was previously most recently used to implement a prior version
of `syntax-parameterize`, an unused struct which was removed in
bf48460, and had an unnecessary reference
in compatability-lib (removed in racket/compatibility#15).
Now that those are all gone, we can remove it.
jesboat added a commit to jesboat/racket that referenced this pull request Feb 26, 2026
This was previously most recently used to implement a prior version
of `syntax-parameterize`, an unused struct which was removed in
bf48460, and had an unnecessary reference
in compatability-lib (removed in racket/compatibility#15).
Now that those are all gone, we can remove it.
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