Racket v8.7 Release Thread

The release process for v8.7 will begin in about a week.  If you
have any new features that you want in and are relatively close to
to being done, now is a good time to do that.

Upcoming dates:
- 7th:  Branch day, merge window starts
- 15th: Merge window ends, testing starts
- 22nd: Testing ends
1 Like
The release process for v8.7 has begun: release checkpoints have
been created for all packages in the main distribution, and release
branches have been created when necessary. You can go on using
`master` branches as usual. The main Racket repo's is now bumped to
v8.7.0.1 (to avoid having two different trees with the same version).

If you have any bug-fixes and changes (including history updates)
that need to go in the release then make sure to specify that in the
commit message by using the word `merge` or `release` or mail the
relevant repo manager [1]) the commit SHA1s. Do not push commits
directly to `release` branches.

Please make sure that code that you're responsible for is as stable
as possible, and let me know if there is any new work that should
not be included in this release.


The time between now and the end of the merge window is for fixing
new errors that prevent proper functioning of major components and
that show up during the preparation for a release. You can also
finalize piece of work that is not yet complete, but please avoid
merging new features.

Note that nightly builds will go on as usual (starting from
v8.7.0.1 and going up as usual), and pre-release builds will be
available shortly at


[1] https://github.com/racket/racket/wiki/release-repo-managers

Upcoming dates:
- 15th: Merge window ends, testing starts
- 22nd: Testing ends
1 Like

@jbclements, just wanted to make sure you saw this: Make `release` a descendant of `stable` by LiberalArtist · Pull Request #4460 · racket/racket · GitHub

Yes. Did my response (sent on a plane so who knows) actually get to you?

Yes, I've just written back. Tl;dr the simple part should be simple, but you were right about:

The file at https://download.racket-l
ang.org/version.txt (used by version/check) currently contains:

((recent "8.6") (stable "8.6"))

Is it supposed to instead have (recent "8.6.900"), since that is up at https://pre-release.racket-lang.org ? It's at least equally possible that I misunderstand what sort of "alpha" version is supposed to be reported there, I just happened to be doing something with it this week.

Testing for the v8.7 release
  (using the v8.6.900 release candidate build)

Search for your name on the checklist page to find relevant items, either
reply when you finish an item (please indicate which item/s is/are done),
or check it off yourself on the checklist page. Also, if you have any
commits that should have been picked, make sure that the changes are in.

Please try to finish your testing by the 1st. Let me know if this will present problems.

The checklist page is at:

Release candidates are at:

Please use these installers (or source bundles) -- don't test from
your own git clone (don't test the `master' branch by mistake!).
To get the tests, you can do this:

  cd ...racket-root...
  ./bin/raco pkg install -i --auto main-distribution-test

First answer: no idea. So I took a quick 'git blame' look at check.rkt and... hey, you wrote most of it! :slight_smile: It looks to me like Eli built in support for the notion of an alpha version in 2008. My guess would be that the subsequent thinking was that there was no compelling reason to direct anyone to anything other than the most recent stable version.


All I know about version/check is that it once gave me trouble when I had network issues :slight_smile: (I can't find the bug report I thought I'd written at the time, but here's the PR that fixed it: version/check: use https; actually enforce timeout; guard reading params by LiberalArtist · Pull Request #3713 · racket/racket · GitHub)

You inspired me to do a bit more Git sleuthing. From what I can see, it looks like the current code dates from 2005 (PLT Scheme v300), when it replaced some older code that also dealt with package versions (for PLaneT packages, I guess?) and other stuff: Removed old version code, new version is greatly simplified. · racket/racket@88bb2b3 · GitHub

The only use of check-version I know about is in:

which is supported by string constants from:

From all of that, it seems like, of the possible results from get-version, the `ok, `(newer ,version), and `(error ,message [,additional-info]) cases aren't affected at all by whether we use the alpha field at https://download.racket-lang.org/version.txt, and DrRacket doesn't distinguish the `(newer ,version ,alpha) case (meaning You have an old version, please upgrade to `version' you may consider also the alpha version) from the `(newer ,version) case.

That leaves only the `(ok-but ,version) case, meaning You have a fine stable version, but note that there is a newer alpha. Note that this is not the result you would get running 8.6.900 if 8.6.901 became available! DrRacket does have UI for this case, but it is used only when the Help|Check for Updates… menu item is explicitly invoked, never for automatic checks, even if the user has enabled them.

More broadly, the string constant, code, and documentation talks about a newer alpha-release, but that's not really a term we use outside of this library. (I don't know about the c. PLT Scheme v300 era.) I've been mentally translating it as "release candidate" (a.k.a. "pre-release"), but it could also conceivably mean "snapshot build" or something.

I haven't found the code that actually creates or updates the https://download.racket-lang.org/version.txt file, so I'm not sure how easy or difficult it would be to change things, if changes were wanted.

I don't have a strong opinion about this.

I can see it being mildly useful to be able to programmatically tell if there's a release candidate out. If https://download.racket-lang.org/version.txt answered that question, I would make the answer usable in Guix tooling—but I wouldn't change the status quo on my account! If that is indeed the functionality in question, it seems like there are other ways to get that information, maybe from https://pre-release.racket-lang.org/installers/table.rktd or by checking if a release branch exists.

One thing we definitely should not do is change https://download.racket-lang.org/version.txt to no longer list an alpha version at all (even if we continue to list a redundant one): that would cause errors in old versions of Racket.

Unless anyone has other thoughts, I'd be inclined to just document that check-version is not currently a reliable way to find out about "release candidate", "pre-release", or "snapshot" versions and leave the release process as-is.

  • Re your suggestion of not creating the tag until some testing, the original motivation for creating the tag as soon as the version is bumped (for releases) is to avoid a situation where there are two builds with the same version number that are not the same code, so there's no chance of confusion. There was even at some point a bit in the release where I faked the new version number so I can update things like screenshots (and some Shriram-related things too?). Probably mostly moot now.

  • The reason for the "alpha" releases were due to some big-ish changes that streched over a longer period (e.g., 369.100). All of that is before "rc" was as common as it is now. (If that code is doing the same thing it did then it's probably crying out for attention.)

  • I have a vague memory of making up the format of version.txt instead of the older code which was some other filename. To change the format you can play the same game by making the code use some new version.rktd file with whatever's needed, and leave version.txt to point at the new version so there's no problem with older versions.

  • By some cosmic coincidence, I went over this branching approach in the last few weeks (due to $work), and implemented roughly the same strategy, automated via a github action. One thing that I've noticed (~two days ago) is that due to merges going only from master to release to stable but not the other way, GH shows stable as being way ahead of master. I figured that an improvement there would be exactly the kind of -s ours fake merge to avoid that confusion.


Philip, I'm on board with the suggestion of not doing much other than documenting the current situation. Your language, "I'd be inclined," suggests that you might not be averse to coming up with this language?

Good to hear from you, and to have this documented.

This makes sense. (@jbclements also pointed me to some complications off-list.) If we try to revisit this idea next release, one thing I noticed is that release-catalog/add-tags.rkt at master · racket/release-catalog · GitHub currently creates tags using the GitHub API: maybe creating tags locally could keep some benefits but be more flexible? But I also think it might be a better use of effort to just do as @samth suggested elsewhere:

This is useful context, thanks! The fact that "alpha" releases were a different sort of thing than either "pre-release"/"release candidate" or "snapshot" builds currently (both of which are relevant for a fairly short time) reinforces my thinking that we should leave this alone and just document the current state of affairs. If someday someone wants to add new version-related functionality that would be useful in the current context (e.g. warning you if you have a stale release candidate), as you say, they can add a new file or something: that seems better than overloading the meaning of "alpha" anyway.

Sure, I'll try to make a PR soon.

Interesting! To be concrete, are you suggesting that, after tagging the release and updating stable, we should git checkout master && git merge -s ours stable? That seems like a nice enhancement! In addition to showing which branch is "ahead", it would also record where we were in the history of master when we released a given version.

I adjusted a diagram I made earlier for @jbclements to reflect @elibarzilay's suggestion (AIUI), because I found a visualization helped me understand the details:

This makes sense to me, I think. I'm currently wrestling with the fact that our most recent first-ever merge of stable into the release branch means that my "commits that appear on the release branch but not in the last tagged release" now includes all cherry-picked commits going back to the beginning of time. I believe this won't happen again, though.

@LiberalArtist , can you formulate what you & Eli are proposing as they would appear in a checklist? That is:

  • branch day: (execute these commands)
  • release day: (execute these commands)

I do not know whether they were bugs, but I show a few things I have noticed.

1. a struct with #:transparent + a SRFI-1's circular list shows messed print-outs.

I had made a program of the Old-maid. The source is here.
This works fine, but let's say, when I wanted to see an environmental value, w, embedded in the game-eval, I noticed the display shows something strange.

;; Sorry, comments are written in Japanese.
(define (oldmaid n)
  (let loop ((w (initialize n)))
    ;;; ここで例外処理を記述する
    (with-handlers ((exn:fail:contract?
                     ;;; 例外処理
                     (lambda (ext) (display "入力が不正です\n")
                       (loop w))))
      ;;; 本体
      (if (game-ends? w)
          (display (showResult (world-id1 w)))
          ;;; Read-Eval-Print loop
          (begin (display w) ;; Adding this for debugging, for instance
                 (loop (print (world-go (input w) w))))))))


You see, the w, or the World struct has an circular list in it, and the process itself has no problem at all; however, the print shown becomes messed-up.
The existence of a circular list may affect to the printing.
You see, for instance, #0=#(struct:Card C 5) #1=(0 1 2 3 . #1#) (#0# #(struct:Card H 5)) and those are meaningless. The printing of struct is affected.

2. module seems to work incorrectly
According to module syntax, if we provided a cake.rkt file as shown bellow:

;;#lang racket

(module cake racket
  (provide print-cake)
  (define (print-cake n)
    (show "   ~a   " n #\.)
    (show " .-~a-. " n #\|)
    (show " | ~a | " n #\space)
    (show "---~a---" n #\-))
  (define (show fmt n ch)
    (printf fmt (make-string n ch))

it should be "required"; however, it does not work.


3. module having pictures gives an error.

I had made a binary-search tree like this:

#lang racket

(provide list->bst bst-search *av-list*)

(define (list->bst lst (cmp <) #:key (fn identity))
  (define (loop lst cmp fn)
    (if (null? lst)
        (let ((pivot (car (drop lst (quotient (length lst) 2)))))
          (let ((left (loop (filter (lambda (x)
                                      (cmp (fn x) (fn pivot)))
                                    lst) cmp fn))
                (right (loop (filter (lambda (x)
                                       (cmp (fn pivot) (fn x)))
                                     lst) cmp fn)))
            (cond ((list? pivot) `(,@pivot ,left ,right))
                  ((pair? pivot) (match-let (((cons k v) pivot))
                                   `(,k ,v ,left ,right)))
                  (else `(,pivot ,left ,right)))))))
  (loop (sort lst cmp #:key fn) cmp fn))

(define (bst-search v tree (cmp equal?) #:keyfn (kfn <) #:key (fn car))
  (match tree
    ('() #f)
    (`(,lvp ... ,left ,right)
     (cond ((cmp v (fn lvp)) lvp)
           ((kfn v (fn lvp)) (bst-search v left cmp #:keyfn kfn #:key fn))
           (else (bst-search v right cmp #:keyfn kfn #:key fn))))))

[ image removed by admin ]
[ image removed by admin ]

The pictures are embedded in the source file.
The problem is, if you want to "require" this, the error occurs.



  1. Are you familiar with how Racket prints circular lists? You can see an example at


Specifically, things like #0 are used to define "placeholders" to allow printed representations to refer to themselves.

  1. It looks to me like you're running the require in the interactions window. There are circumstances in which modules can be bound to quoted values like this, but they're uncommon. (Put differently: it doesn't appear to me that this is a bug?).

Here's some code that works; tell me what about this is different from what you want:

#lang racket

(module cake racket
  (provide print-cake)
  (define (print-cake n)
    (show "   ~a   " n #\.)
    (show " .-~a-. " n #\|)
    (show " | ~a | " n #\space)
    (show "---~a---" n #\-))
  (define (show fmt n ch)
    (printf fmt (make-string n ch))

(require 'cake)

(print-cake 34)
  1. haven't looked at #3

Hello. Mr. jbclements.

Are you familiar with how Racket prints circular lists? You can see an example at

Yes. I was familiar with that in ANSI Common Lisp.

The problem is not the expression like #0='(1 . #0#). The unrelated thing is influenced by circular-list expression. That is the problem.

Let me explain step by step.
The first situation is like this.


The World struct, or w consists of card, circular-list, discarded, dpair, id1, id2, and players. Well, anyway, the second slot has an circular-list.
And all the stuffs are displayed O.K.
But in the second turn,


Do you notice? The #0 stuff spreads over the other stuffs.
#0=#(struct:Card S J) does not mean anything, nor (#0# #(struct:Card C J)).
They are not circular lists, and I did of course not mean it.
#0=#(struct:Card S J) should be just (struct:Card S J) and (#0# #(struct:Card C J)) should be just #(struct:Card C J).
However, the game progresses with no problem; therefore, I doubted this is a sort of bug around displaying.

It looks to me like you're running the require in the interactions window.

Yes, it does, but that is not what I made. What I did was on the Racket Guide.
Thus, if what I wrote was not compatible to the present Racket, somebody should rewrite it.
I barely remember, anyway, this module style worked in PLT Scheme era. Probably.
So I think this happens quite recently. Perhaps with Chez Scheme? I do not know, though.

haven't looked at #3



On circular lists

What you're seeing is a combination of printing of sharing (eg #0#=(list 1 2)) and the display version of printing of structures that do not have a "read"-able form but are transparent

Consider this program:

#lang racket
(define z (shared ([x (list 1 2 3 x)]) x))
(struct p (v) #:transparent #:mutable)
(displayln z) ; prints #0='(1 2 3 #0#)
(displayln (p 1)) ; prints #(struct:p 1)
(displayln (p z)) ; prints #(struct:p #0=(1 2 3 #0#))
(displayln (shared ([x (list (p x))]) x)) ; prints #0=(#(struct:p #0#))

On modules and the REPL

I think you put the code in a file and then did something with it. That's not what the Guide is showing. Instead, it's demonstrating this interaction:

[samth@huor:~ plt] racket
Welcome to Racket v8.7.0.3 [cs].
> (module cake racket
    (provide print-cake)
    (define (print-cake n)
      (show "   ~a   " n #\.)
      (show " .-~a-. " n #\|)
      (show " | ~a | " n #\space)
      (show "---~a---" n #\-))
    (define (show fmt n ch)
      (printf fmt (make-string n ch))
> (require 'cake)
> (print-cake 1)
 |   | 

which works correctly as the Guide shows.

Compilation with images

The problem here is that you can't compile the file with the images in it to a zo file. (You can see the same error when running raco make on the file in question.) DrRacket is trying to automatically compile the file, which leads to that error. You can work around the problem by disabling "Populate compiled directories" in the "Language" dialog (go to the Language menu, select Choose Language, then click Show Details to see this option).