Racket v9.0 is now available

We are pleased to announce Racket v9.0 is now available from https://download.racket-lang.org/.

Racket 9.0 is here!

A major release is always exciting and Racket 9.0 is no exception in that it introduces Parallel Threads. While Racket has had green threads for some time, and supports parallelism via futures and places, we feel parallel threads is a major addition.

To read more about parallel threads, take a look at the new blog post, at Parallel Threads in Racket v9.0

  • Parallel threads can be created using the #:pool argument to thread creation. 11.1 Threads
  • Threads created with #:keep set to 'results will record their results for later retrieval with thread-wait. 11.1 Threads

More details about parallel threads are available in the Racket Guide and Reference.

We would like to give a special thank you to the community members whose testing of the snapshot builds helped make this a release-quality addition: @dominik.pantucek, @bogdan, @damien_mattei, @LiberalArtist, @jjsimpso and @ndykman :clap:

Other exciting updates:

  • The black-box wrapper prevents the optimizing compiler from optimizing away certain computations entirely. This can be helpful in ensuring that benchmarks are accurate. 10.8 Black-Box Procedure
  • The decompile-linklet function can map linklets back to s-expressions. 14.14 Linklets and the Core Compiler
  • When using BC Racket, the processor-count function is changed to return the parallel count. 11.4 Futures
  • We now distribute "natipkg" packages for AArch64, useful for package-build and package-testing infrastructure.
  • Check Syntax now tracks identifiers more deeply nested in the "origin" field of syntax objects.
  • The math library includes Weibull distributions.

...and many other repairs and documentation improvements!

Don’t forget to run raco pkg migrate 8.18 :grin:

Thank you

The following people contributed to this release:

Alexander Shopov, Anthony Carrico, Bert De Ketelaere, Bogdan Popa, Cadence Ember, David Van Horn, Gustavo Massaccesi, Jade Sailor, Jakub Zalewski, Jens Axel Søgaard, jestarray, John Clements, Jordan Johnson, Matthew Flatt, Matthias Felleisen, Mike Sperber, Philip McGrath, RMOlive, Robby Findler, Ruifeng Xie, Ryan Culpepper, Sam Phillips, Sam Tobin-Hochstadt, Sebastian Rakel, shenleban tongying, Shu-Hung You, Stephen De Gabrielle, Steve Byan, and Wing Hei Chan.

Racket is a community developed open source project and we welcome new contributors. See racket/README.md to learn how you can be a part of this amazing project.

Feedback Welcome

Questions and discussion welcome at the Racket community on Discourse or Discord.

Please share

If you can - please help get the word out to users and platform specific repo packagers

Racket - the Language-Oriented Programming Language - version 9.0 is now available from https://download.racket-lang.org

See https://blog.racket-lang.org/2025/11/racket-v9-0.html for the release announcement and highlights.

Racket Discourse Racket Discord
Mastodon Follow Follow Racket on Bluesky

6 Likes

Apologies - we appear to have a problem with the threads blog post for the moment - please bear with us.

If you can't wait, you download and render racket-lang-org/blog/_src/posts/2025-11-23-parallel-threads.scrbl at master · racket/racket-lang-org · GitHub to html to peek.

s.

The download URLs are all 404. Is this known?

1 Like

Apologies - the platform download button works,
image

,but the links in More Installers and Checksums (https://download.racket-lang.org/releases/9.0/) are failing.

I've let the team know. Will try to update you when it is fixed.

Stephen

1 Like

The various link issues should be fixed, now.

1 Like

Thanks and congratulations on v9!

I appreciate there a new features, but curious should this .0 release be considered differently from 8.x releases in terms of breaking or experimental changes? (I am asking as the Fedora package maintainer, but not really a heavy racket user.)

Thank you for maintaining the Fedora package maintainer :heart_eyes:

My understanding is there are not expected to be breaking changes.

The parallel threads post addresses backwards compatibility: Parallel Threads in Racket v9.0 - I've copied that part of the blog post below:


Backward Compatibility

If a library uses mutable variables or objects, either publicly or internally, then it must use locks or some other form of concurrency control to work properly in a multithreaded context. Racket already has concurrency, and the expectation for libraries to work with threads does not change with the introduction of parallel threads. Racket’s semaphores, channels, and other synchronization constructs work the same with parallel threads as concurrent threads. Even programs that use lock-free approaches based on compare-and-swap operation (such as box-cas!) continue to work, since Racket’s compare-and-swap operations use processor-level primitives.

Still, there are a few concerns:

  • Racket’s coroutine threads offer the guarantee of sequential consistency, which means that effects in one thread cannot be seen out-of-order in another thread. Parallel threads in Racket expose the underlying machine’s memory-consistency model, which may allow reordering of memory effects as observed by other threads. In general, a weak memory model can be an issue for code not intended for use with threads, but Racket— more precisely, Chez Scheme— always guarantees the memory safety of such code using memory fences. That is, Racket code might observe out-of-order writes, but it never observes ill-formed Racket objects. The fences are not new, and they are part of the same write barrier that already supports generational garbage collection and the memory safety of futures. Although sequential consistency supports lock implementations that don’t work with weaker memory models, so they would work with coroutine threads and not parallel threads, we have not found any such implementations in Racket libraries.
  • Some Racket libraries use atomic mode for concurrency control. Atomic mode in Racket prevent coroutine thread swaps, and entering atomic mode is a relatively cheap operation within Racket’s coroutine scheduler. When a parallel thread enters atomic mode, then it prevents other coroutine threads from running, but it does not prevent other parallel threads from running. As long as atomic mode is used consistently to guard a shared resource, then it continues to serve that role with parallel threads.Entering atomic mode is a much more expensive operation in a parallel thread than in a coroutine thread; in many cases, Racket core libraries that need finer-grained locking more specifically need to move away from using atomic mode. Still, making atomic mode synchronize a parallel thread with coroutine thread provides a graceful fallback and evolution path.
  • Foreign functions that are called by Racket in a coroutine threads are effectively atomic operations when there are no parallel threads, since a coroutine swap cannot take place during the foreign call. It’s rare that this atomicity implies any kind of lock at the Racket level, however, and the foreign function itself is either adapted to operating-system threads or not. Racket can already create operating systems threads through dynamic-place, and foreign-function bindings have generally been adapted already to that possibility.

The greater degree of concurrency enabled by parallelism exposed some bugs in our existing core libraries that could have been triggered with coroutine threads, but hadn’t been triggered reliably enough to detect and repair the bugs before. Beyond those general improvements, our experience with pre-release Racket is that parallel threads have not created backward-compatibility problems.

1 Like

Maybe a shorter answer is that Racket does not use SemVer, which was not really a thing when Racket's current versioning Scheme was adopted. Incrementing the major version means some noteworthy change happened that's useful to prominently track in the timeline. It does not mean some sorry of breaking change: all Racket releases have the same compatibility commitment.

For comparison, other major versions mean:

  • 8.0 Racket CS is the default implementation
  • 7.0 Switch to Racket-implemented expander and module system (from C)
  • 6.0 New package system (successor to PLaneT) a and restructuring almost all of Racket into packages
  • 5.0 Renamed to “Racket” and #lang racket recommended instead of #lang scheme
  • 4.0 Beginning of current versioning system, switch to immutable pairs in #lang scheme

Some might argue that a new feature is more likely to have bugs, but on the other hand, as noted in the blog post, parallel thread have revealed, and led to fixes for, preexisting bugs.

3 Likes