RacketCon 2026 (sixteenth)

Table of Contents

1. Overview

Written from the published program on 2026-10-01, before the conference. The examples below were run on Racket 8.15 and Guile 3.0.10. Previous edition: RacketCon 2025.

2. Recordings

The Racket channel's playlist (sixteenth RacketCon) 2026 holds all eleven talks on the program, uploaded 2026-10-07. Each talk below links its own video; titles on YouTube match the program.

Talk Video
On Notation 1:10:12
Type Inference With Logical Types For Rhombus 35:45
Language-Oriented Low-Level Programming with Pille 36:30
Treason 33:20
Herbie 48:28
Effect Handlers in cio 34:14
BrandX 45:51
A New Foreign-Function Interface: ffi2 38:02
Uke: Immutable Dataframes for Racket 41:10
The State of Racket 37:47
Racket Town Hall 28:14

3. Schedule

3.1. Saturday, October 3

Time Speaker Talk
9:00 Pat Hanrahan On Notation (keynote)
10:30 Fred Fu Type Inference With Logical Types For Rhombus
11:10 Lucas Myers Language-Oriented Low-Level Programming with Pille
1:30 Mike Delmonaco Treason: Making Macros and IDE Services Work Together
2:10 Pavel Panchekha Herbie: Improving Floating-point Accuracy
3:30 JJ Effect Handlers in cio
4:10 Ryan Culpepper BrandX: Commoditizing OOP with Interfaces, Generics, and Contracts

3.2. Sunday, October 4

Time Speaker Talk
9:00 Sam Phillips Uke: Immutable Dataframes for Racket
9:40 Matthew Flatt A New Foreign-Function Interface: ffi2
11:00 Sam Tobin-Hochstadt The State of Racket
11:30 Racket Management Racket Town Hall

Times are Pacific.

4. How the talks relate

Four threads run through the nine talks, and each has a counterpart at Clojure/conj 2026, held the same week.

Thread RacketCon talks Same question elsewhere
Reaching native code Pille, ffi2 jank on LLVM; babashka's FFI; Panama in Fast, Lean, Native Clojure
Types and checks without a rewrite Type inference, BrandX Clojure 1.13 checked destructuring; a new protocol implementation
Tools that understand macros Treason clojure-lsp and clj-kondo; a source inspector for Hiccup
Control and data as libraries cio, Uke, Herbie core.async; tech.ml.dataset

The keynote sits above all four: notation is what a language-oriented community is arguing about in every one of them.

5. Saturday

5.1. On Notation — Pat Hanrahan

Video: YouTube.

Keynote. Canon Professor Emeritus at Stanford; led the design of RenderMan at Pixar; co-founded Tableau; 2019 Turing Award. No abstract is published.

RenderMan's shading language and Tableau's visual query language are both notations built for one domain, which is the thing Racket exists to make cheap. The same argument, from the other side, opened Clojure/conj's source inspector talk with Bret Victor.

5.1.1. Prior art: Fortress, a language that set out to look like mathematics

The Fortress Language Specification, Version 1.0 α (Sun Microsystems, September 19, 2006; 411 pages) is the most deliberate attempt at mathematical notation in a general-purpose language. Its authors are Eric Allen, David Chase, Joe Hallett, Victor Luchangco, Jan-Willem Maessen, Sukyoung Ryu, Guy L. Steele Jr. and Sam Tobin-Hochstadt, who gives the State of Racket on Sunday.

Four ideas from the spec, quoted from sections 2.4, 2.12, 2.13 and 16.7:

Rendering
programs are typed in ASCII and displayed as mathematics. f(x) = x^2 + sin x - cos 2 x renders with a superscript and italics; a[i] renders as a subscript. Unicode can be typed by name: GREEK_CAPITAL_LETTER_LAMBDA becomes Λ, lambda becomes λ, SUM becomes Σ, CUP becomes ∪.
Comprehensions
set-builder notation, computed in parallel by default: {x/2 | x ← t}, {x + y | x ← s, y ← t}, {x | x ← t, x ≥ 0}.
Big operators
factorial(n) = PRODUCT[i <- 1:n] i, rendered as a capital pi over i ← 1:n.
Juxtaposition
2 x is multiplication and sin x is application. Which one depends on types and whitespace, so the parser holds a run of juxtaposed terms "in abeyance", type-checks each element, and only then rewrites it into a tree. The spec gives the case it forbids: if n is both a functional method and a local, na is a static error.

That last rule is the cost of mathematical notation stated plainly: the grammar cannot be parsed without the types.

5.1.2. More examples from the Fortress spec

Quoted from chapter 2 of the spec. The text was extracted from the PDF, which loses the rendering, so superscripts are restored here by hand and the blackboard-bold types are written as ℝ and ℤ.

Juxtaposition is multiplication, and a function next to its argument is a call (section 2.6):

factorial(n) =
    if n = 0 then 1
    else n factorial(n − 1) end

sin x

Comparisons chain as on paper, and parameters take defaults by keyword (2.6.1):

makeColor(red: ℤ64 = 0, green: ℤ64 = 0, blue: ℤ64 = 0) =
    if 0 ≤ red ≤ 255 ∧ 0 ≤ green ≤ 255 ∧ 0 ≤ blue ≤ 255
    then Color(red, green, blue)
    else throw Error end

makeColor(green = 255)

Contracts sit in the function header, before the body; result is bound in ensures (2.6.4):

factorial(n)
    requires n ≥ 0
    ensures result ≥ 0
    = if n = 0 then 1
      else n factorial(n − 1) end

Loops are parallel unless asked otherwise, so this may print in any order (2.8), and atomic is how parallel code shares state (2.9):

for i ← 1:10 do
    print(i " ")
end
-- possible output: 5 4 6 3 7 2 9 10 1 8

atomic do
    x += 1
    y += 1
end

Units and dimensions are part of the type, checked statically (2.10):

kineticEnergy(m: ℝ kg, v: ℝ m/s): ℝ kg m²/s² = (m v²)/2

v: ℝ m/s = (3 meters + 4 meters)/5 seconds    -- fine
v: ℝ m/s = (3 meters + 4 seconds)/5 seconds   -- static error: meters + seconds
v: ℝ m/s = (3 meters + 4 meters)/5            -- static error: m is not m/s

kineticEnergy(3.14 kg, 32 f/s in m/s)         -- unit conversion

Tests range over a finite collection; properties quantify over a type (2.14):

test factorialResultLarger[x ← 0:100] = x ≤ factorial(x)
property factorialResultAlwaysLarger = ∀(x: ℤ) (x ≤ factorial(x))

Where each idea went afterwards:

Fortress, 2006 Where it lives now
requires / ensures Racket contracts; Saturday's BrandX talk is about contracts on interfaces
property ∀(x: ℤ) property-based testing: QuickCheck, test.check, rackcheck (Treason uses it)
units in the type F# units of measure; libraries elsewhere
parallel for by default not adopted by any mainstream language; Clojure's pmap and Racket's futures are opt-in
type-directed juxtaposition nowhere; Haskell and Rhombus both chose a grammar that parses without types

The "where it lives now" column is from memory, except that Treason depends on rackcheck, which its info.rkt shows.

Sam Tobin-Hochstadt is on the spec's author list, gives the State of Racket on Sunday, and works on Typed Racket. A question in the keynote that brought up Fortress would have had one of its authors in the room. Fortress's two hardest problems, type-directed parsing and parallel-by-default evaluation, are the two Racket never took on; its contracts and its typed treatment of an untyped notation are both things Racket did take on.

5.1.3. The same notation, where it survived: Haskell and Racket

Haskell kept most of it without the type-directed parsing: comprehensions are set-builder notation, and operators can be Unicode with declared fixity, so ∩ binds tighter than ∪ as it does on paper. Run on GHC 9.14.1:

{-# LANGUAGE UnicodeSyntax #-}
import Data.List (union, intersect)

infixl 6 ∪
infixl 7 ∩
(∪), (∩) :: Eq a => [a] -> [a] -> [a]
(∪) = union
(∩) = intersect

infix 4 ∈
(∈) :: Eq a => a -> [a] -> Bool
(∈) = elem

halves t        = [x / 2 | x <- t]               -- {x/2 | x ← t}
sums s t        = [x + y | x <- s, y <- t]       -- {x + y | x ← s, y ← t}
nonNegative t   = [x | x <- t, x >= 0]           -- {x | x ← t, x ≥ 0}
factorial n     = product [i | i <- [1 .. n]]    -- PRODUCT[i <- 1:n] i

-- halves [2, 4, 6]                 => [1.0,2.0,3.0]
-- sums [1, 2] [10, 20]             => [11,21,12,22]
-- nonNegative [-1, 0, 3]           => [0,3]
-- factorial 10                     => 3628800
-- [1, 2, 3] ∪ [3, 4] ∩ [4, 5]      => [1,2,3,4]   (∩ first)
-- 3 ∈ [1, 2, 3] ∪ [4]              => True

What Haskell gave up is juxtaposition as multiplication: 2 x is application of 2. That single choice is what lets it parse without types.

Racket keeps prefix notation and puts the same ideas in named forms. Run on Racket 8.15:

(for/list ([x (list 2 4 6)]) (/ x 2))                ; => (1 2 3)
(for*/list ([x (list 1 2)] [y (list 10 20)]) (+ x y)) ; => (11 21 12 22)
(for/product ([i (in-range 1 11)]) i)                ; => 3628800, Π
(for/sum ([i (in-range 1 11)]) (* i i))              ; => 385, Σ
Idea Fortress (2006) Haskell Racket
Set-builder comprehension braces, ← generators brackets, <- generators for/list
Big operators SUM, PRODUCT as Σ, Π sum, product over a list for/sum, for/product
Unicode operators typed by name, rendered yes, with declared fixity any identifier; prefix only
Juxtaposition multiplication or call, by type always application none; parentheses
Infix yes yes not in Racket; yes in Rhombus

Rhombus is where Racket's answer moved: infix operators with declared precedence over the same macro system, and the enforestation step that Pille reuses on Saturday afternoon.

Questions to bring to the keynote: does notation belong in the language, in the renderer, or in the editor? Fortress put it in all three. Tableau, which Hanrahan co-founded, put it in the interface and kept the user away from syntax altogether.

5.2. Type Inference With Logical Types For Rhombus — Fred Fu

Video: YouTube.

PhD candidate at Indiana. The problem: a Typed Racket program imports a macro from untyped Racket, the macro expands to a lambda, and nobody can annotate the generated parameters. Local inference does not infer lambda parameters, so the checker rejects the code. His prototype combines occurrence typing with algebraic subtyping.

Occurrence typing is the part to have in mind: the type of a variable narrows after a test on it.

#lang typed/racket
(: describe (-> (U String Integer) String))
(define (describe v)
  (if (string? v)
      (string-append "s:" v)          ; v is a String here
      (number->string (add1 v))))     ; and an Integer here
(describe "a")   ;=> "s:a"
(describe 41)    ;=> "42"
Language The same idea
TypeScript narrowing by typeof and type guards
Kotlin smart casts
Python isinstance narrowing in mypy and pyright
Clojure no static counterpart; core.typed took occurrence typing from Typed Racket

The comparison rows are from memory, not checked.

5.3. Language-Oriented Low-Level Programming with Pille — Lucas Myers

Video: YouTube.

PhD student at Northwestern, advised by Robby Findler. Pille grafts Rhombus's enforestation, the step that turns a flat token stream with infix operators into a tree, onto a new core language with an LLVM-based compiler. The macros stay; the Racket VM goes, and with it the runtime that rules out microcontrollers.

This is the same move as jank, presented at Clojure/conj two days earlier: keep the language's metaprogramming, replace the host with LLVM. jank keeps Clojure's runtime semantics and reaches for C++ interop. Pille gives up the runtime to reach the bottom of the stack.

5.4. Treason: Making Macros and IDE Services Work Together — Mike Delmonaco

Video: YouTube.

Software engineer at AWS. Macros get in the way of IDE services when the program is broken or half-typed, because expansion stops at the first error. Treason's expander recovers and keeps collecting. The stated contribution is spec-driven subexpression expansion: syntax-class annotations say which parts of a macro use are expressions, so they can be expanded even when the macro use around them is broken.

Clojure's answer to the same problem is to not expand at all: clj-kondo and clojure-lsp analyse source statically and need a hint for every unfamiliar macro. Treason takes the opposite bet. He spoke last year on a match-like DSL for deep immutable updates.

5.5. Herbie: Improving Floating-point Accuracy — Pavel Panchekha

Video: YouTube.

Associate Professor at Utah. Two ways of writing the same formula can differ enormously in accuracy; Herbie searches for the accurate one. Ten years of writing it in Racket.

The standard example, run here. Both functions compute √(x+1) − √x:

#lang racket
(define (naive x) (- (sqrt (+ x 1)) (sqrt x)))
(define (rewritten x) (/ 1 (+ (sqrt (+ x 1)) (sqrt x))))
(for ([x '(1e0 1e8 1e16)])
  (printf "~a  naive ~a  rewritten ~a\n" x (naive x) (rewritten x)))
1.0  naive 0.41421356237309515  rewritten 0.4142135623730951
100000000.0  naive 5.000000055588316e-5  rewritten 4.9999999874999996e-5
1e+16  naive 0.0  rewritten 5e-9

At 10^16 the naive form returns zero. The subtraction cancels every significant digit; the rewritten form has no subtraction. Herbie finds that rewrite without being told.

5.6. Effect Handlers in cio — JJ

Video: YouTube.

cio is an untyped effect-handler library for Racket and for Guile. An effect handler separates asking for something from deciding what the answer is, and the handler may resume the asker.

The primitive underneath, in Guile, with no library. The program asks; the handler answers twice:

(define tag (make-prompt-tag "ask"))
(define (ask question) (abort-to-prompt tag question))
(define (program) (+ 1 (ask 'how-many)))

(call-with-prompt tag program
  (lambda (k question) (list question (k 41) (k 99))))
;;=> (how-many 42 100)

k is the rest of program from the point it asked. Calling it twice is what exceptions cannot do.

Language Nearest thing
Racket, Guile delimited continuations: prompts and abort
OCaml 5 effect handlers in the language
Koka, Eff typed effect handlers
Common Lisp the condition system: handlers that resume, via restarts
Clojure none on the JVM; core.async's go rewrites to a state machine instead

The comparison rows are from memory. That the library targets Guile as well as Racket is the reason to watch this one from a Guile project.

5.7. BrandX: Commoditizing OOP with Interfaces, Generics, and Contracts — Ryan Culpepper

Video: YouTube.

Racket developer, macros and library design. A new library for OOP through interfaces and generic functions with proper contract support, motivated by limits in racket/class and racket/generic.

The neighbours are CLOS generic functions and Clojure protocols. Chris Nuernberger's Clojure/conj talk the day before proposed a replacement protocol implementation for Clojure on similar grounds: the built-in one has limits that only show at scale.

6. Sunday

6.1. Uke: Immutable Dataframes for Racket — Sam Phillips

Video: YouTube.

An opinionated dataframe library: immutable, and careful about copying. Racket already has several dataframes.

The Clojure counterpart is tech.ml.dataset, which is columnar and functional-by-default over typed buffers. The question to carry in: what does "efficient about copying" mean without persistent data structures underneath?

6.2. A New Foreign-Function Interface: ffi2 — Matthew Flatt

Video: YouTube.

Racket's FFI (Eli Barzilay, about 2004) is dynamic and convenient. Chez Scheme's ftypes (Andy Keep, about 2011) is static and fast, with compact foreign pointers and cheap checks. ffi2 brings the two together, with small changes to Chez Scheme.

System How it reaches C
Racket ffi/unsafe dynamic, macro-built, no C stub
Chez ftypes static layout known at compile time
Guile (system foreign): dynamic, pointer and bytevector based
Clojure / JVM Panama (java.lang.foreign), final in JDK 22
babashka its own FFI support, used for libsodium in this week's workshop
jank C++ interop in the language, no binding layer

This table is the week's theme in one place: three Lisp communities shipped or showed a new way to call native code within five days.

6.3. The State of Racket, and Town Hall

Video: The State of Racket; Racket Town Hall.

Sam Tobin-Hochstadt, then questions to Racket management. No abstract.

7. Study: the program mapped, and one talk built

Done on 2026-10-03, the first day of the conference, in two steps: survey the program, then clone one talk's code and run it. The live stream is on BoxCast.

7.1. Step 1: the program mapped

Each link is marked by how it was checked: opened (fetched and read), API (the GitHub or Codeberg API returned the repository), or search (seen only in search results). "Built on" papers are a reasonable lineage picked by topic unless marked as cited by the project itself.

Speaker Handle Code for the talk Built on
Pat Hanrahan (Stanford) phanrahan (API; probably his, not confirmed by an official link) none; a keynote Iverson, Notation as a Tool of Thought, CACM 1980 (search). His own: RenderMan shading language, SIGGRAPH 1990; VizQL, SIGMOD 2006; Terra, PLDI 2013 (search)
Fred Fu (Indiana) capfredf (API) none of its own; Typed Racket is racket/typed-racket Tobin-Hochstadt and Felleisen, Logical Types for Untyped Languages, ICFP 2010; Dolan and Mycroft, MLsub, POPL 2017; Parreaux, The Simple Essence of Algebraic Subtyping, ICFP 2020 (search). His own, as Yuquan Fu: Type Checking Extracted Methods, Programming 2022 (opened)
Lucas Myers (Northwestern) distractedlambda (API) distractedlambda/pille (API; README says not on the package catalog) Rafkind and Flatt, Honu, GPCE 2012; Flatt et al., Rhombus, OOPSLA 2023 (search)
Mike Delmonaco (AWS) quasarbright (API) quasarbright/treason, cloned and built below; editor client treason-vscode (API) Culpepper and Felleisen, Fortifying Macros, ICFP 2010; Ballantyne, Gamburg and Hemann, ICFP 2024 (syntax-spec) (search). He is the second-largest contributor to syntax-spec (API)
Pavel Panchekha (Utah) pavpanchekha (API) herbie-fp/herbie (API); package herbie (catalog, opened) Herbie's own paper list has 22 entries (opened), starting with Panchekha et al., PLDI 2015. The only talk on the program with its own papers
JJ (Vancouver) Codeberg apropos (API) codeberg.org/apropos/cio (API); not on GitHub, not in the Racket catalog Cited by the cio README: Effekt's Effects as Capabilities, OOPSLA 2020, and two follow-ups (opened README)
Ryan Culpepper rmculpepper (API) rmculpepper/racket-brandx (API); packages brandx, brandx-lib (catalog, opened) Flatt, Findler and Felleisen, Scheme with Classes, Mixins, and Traits, APLAS 2006 (search)
Sam Phillips samdphillips (API) samdphillips/uke (API; Apache-2.0); packages uke, uke-lib and two more (catalog, opened) none cited by the project
Matthew Flatt (Utah) mflatt (API) no repository of its own: pkgs/ffi2 and pkgs/ffi2-lib inside racket/racket (API) Barzilay and Orlovsky, Foreign Interface for PLT Scheme, Scheme Workshop 2004 (opened, in the Racket docs bibliography); Keep and Dybvig, Ftypes, Scheme Workshop 2011 (search)
Sam Tobin-Hochstadt (Indiana) samth (API) none; a state-of-the-project talk Felleisen et al., A Programmable Programming Language, CACM 2018 (search)

Seven talks have public code: Pille, Treason, Herbie, cio, BrandX, Uke and ffi2. Hanrahan, Fu and Tobin-Hochstadt do not.

Things a search gets wrong here:

  • The conference site gives Fred Fu's title as Type Inference With Logical Types For Rhombus; an earlier copy of the program said "For Untyped Languages". His papers are published as Yuquan Fu.
  • cio is on Codeberg. A GitHub user named apropos also exists and is not the same person.
  • ffi2 has no repository of its own.
  • Herbie's catalog entry still points at uwplse/herbie, which redirects to herbie-fp/herbie.

To study each talk:

git clone https://github.com/distractedlambda/pille.git          # Pille; needs LLVM, largest build
git clone https://github.com/quasarbright/treason.git            # Treason
git clone https://github.com/herbie-fp/herbie.git                # Herbie
git clone https://codeberg.org/apropos/cio.git                   # cio; Racket and Guile
git clone https://github.com/rmculpepper/racket-brandx.git       # BrandX
git clone https://github.com/samdphillips/uke.git                # Uke; smallest build
git clone --filter=blob:none --sparse https://github.com/racket/racket.git \
  && git -C racket sparse-checkout set pkgs/ffi2 pkgs/ffi2-lib   # ffi2

7.2. Reading list by talk

A second, wider survey: five research agents, two speakers each, collecting homepages, repositories, related papers and earlier talks. Every link below was requested on 2026-10-03. 66 of 71 returned 200. Four ACM DOIs redirect to the ACM Digital Library, which refuses scripted requests; they are kept. gnu.org did not answer from this machine, so the Guile manual link is unchecked.

Where it differs from the table above: it found Ryan Culpepper's affiliation (Czech Technical University in Prague), a second paper by Fred Fu from September 2026, Pavel Panchekha's sabbatical at NVIDIA, and a second cio repository. It also settles egg's venue as POPL 2021.

7.2.1. Pat Hanrahan, On Notation (Sat 9:00)

Emeritus professor at Stanford (profile). The program has no abstract, and no earlier talk with this title turned up.

His language papers
the RenderMan shading language (SIGGRAPH 1990); Brook for GPUs (2004); Polaris (TVCG 2002), the visualization specification language that led to Tableau's VizQL; Terra (PLDI 2013).
Related talks
shading languages (SFU 2023); Hardware as Software (Lambda Days 2021); an NSF lecture transcript arguing for DSLs with precise semantics.
Probable background
Iverson, Notation as a Tool of Thought (1979 Turing Lecture).

7.2.2. Fred Fu, type inference (Sat 10:30)

GitHub capfredf; 144 commits in Typed Racket. The inference prototype has no public repository.

His papers, as Yuquan Fu (Indiana, with Tobin-Hochstadt)
Type Checking Extracted Methods (‹Programming› 2022); Revisiting Soundness for Occurrence Typing, Semantically (arXiv, September 2026, with Carlo Angiuli), which finds flaws in earlier soundness proofs for occurrence typing and replaces them with a step-indexed logical-relations proof mechanized in Lean.
Same person?
no page says Fred Fu and Yuquan Fu are one person. The evidence is a 2020 capfredf commit on the 2022 paper's topic.
Prior work
the title extends Logical Types for Untyped Languages (ICFP 2010). Algebraic subtyping: MLsub (POPL 2017, code), Dolan's thesis, and Simple-sub (ICFP 2020, code). Castagna et al., Revisiting Occurrence Typing, which formulates occurrence typing with semantic subtyping.

7.2.3. Lucas Myers, Pille (Sat 11:10)

GitHub distractedlambda. distractedlambda/pille holds four Racket packages: the implementation, Rhombus bindings to the LLVM C API (including the ORC JIT), SPMD "varying" types, and the docs and tests. Last commit 2026-10-02. The Rhombus v1.0 announcement lists Pille as a language built on Rhombus.

Prior work
Rhombus (OOPSLA 2023); Honu (GPCE 2012), which introduced enforestation; Terra, an LLVM-compiled low-level language staged from Lua, co-authored by Hanrahan; the enforest docs.

7.2.4. Mike Delmonaco, Treason (Sat 1:30)

GitHub quasarbright; blog; 184 commits in syntax-spec. Built and run in Step 2 below.

Prior work
syntax-spec (ICFP 2024); Fortifying Macros (ICFP 2010); Lean 4's Beyond Notations.
Compared against in the talk
racket-langserver and rust-analyzer.

7.2.5. Pavel Panchekha, Herbie (Sat 2:10)

University of Utah, on sabbatical at NVIDIA (homepage).

Code
herbie-fp/herbie (site), a Racket core with a Rust e-graph component; Rival for interval arithmetic; Odyssey, an interactive interface; FPBench, the benchmark suite.
Papers
Herbie (PLDI 2015); egg (POPL 2021); Combining Precision Tuning and Rewriting (ARITH 2021); Rival (ARITH 2023); equality saturation (POPL 2009).
Talks
PLDI 2015; NSV 2020.

7.2.6. JJ, cio (Sat 3:30)

Codeberg apropos; site toki.la. apropos/cio implements effect handlers for Racket and Guile on prompts; its core forms are define-effect, raise-effect, try, resume and with-effect-handler, and the README names Effekt as the main model. A second repository, racket-guile-control, reimplements Guile's delimited-control primitives in Racket.

Prior work
Effekt and Effects as Capabilities; Plotkin and Pretnar, Handling Algebraic Effects; Racket delimited control (ICFP 2007); Guile prompts.
Other Racket effect libraries
effect-racket, effection.

7.2.7. Ryan Culpepper, BrandX (Sat 4:10)

Czech Technical University in Prague (profile).

Code and docs
rmculpepper/racket-brandx; the docs cover interfaces, generics, bundles, signatures and dependent contracts; the August 2026 announcement gives the motivation. He is testing it by porting his crypto library.
Prior work
his own Fortifying Macros and Debugging Hygienic Macros; racket/generic; Classes, Mixins, and Traits (APLAS 2006); Contracts for First-Class Classes; Units, the model for BrandX's bundles and signatures.
Earlier talk
Making low-level libraries Rackety (RacketCon 2011 slides).

7.2.8. Sam Phillips, Uke (Sun 9:00)

GitHub samdphillips. samdphillips/uke (docs) has dataframe, column, index and store layers; select, group and left-join return new values instead of mutating.

Comparable Racket libraries
data-frame, sawzall, tabular-asa.
Background
Towards Scalable Dataframe Systems (VLDB 2020).

7.2.9. Matthew Flatt, ffi2 (Sun 9:40)

University of Utah (homepage).

Code and docs
the ffi2 docs; the package ffi2-lib, whose source is in racket/racket starting at commit 6927f16 (authored 2026-03-13). Two earlier commits change Chez Scheme: one adds __errno and __alloc foreign conventions, one adds nongenerative define-ftype. The v9.2 notes mention ffi2; Rhombus's ffi library is built on it.
Prior work
Barzilay and Orlovsky, Foreign Interface for PLT Scheme (Scheme Workshop 2004); Ftypes (2011); Rebuilding Racket on Chez Scheme (ICFP 2019).

7.2.10. Sam Tobin-Hochstadt, The State of Racket (Sun 11:00)

Indiana University (homepage); the most commits in Typed Racket. Also a co-author of the Fortress specification, see the keynote section.

Earlier State of Racket talks
2023, 2024, 2025.
Releases since RacketCon 2025
Racket v9.0 (parallel threads); v9.1 (February 2026); v9.2 (ffi2); v9.3 (Markdown docs, faster Check Syntax); Rhombus v1.0 (June 2026, the first stable release) and v1.1.
His Typed Racket papers
Typed Scheme (POPL 2008); Logical Types (under Fu above); Occurrence Typing Modulo Theories (PLDI 2016).

The machine these notes were written on runs Racket 8.15, three releases behind v9.3.

7.3. Step 2: Treason, built and run

Treason at commit f901eee (2026-09-30), MIT licensed. It provides #lang treason and a treason-language-server executable; the editor client handles .tsn files. Run on Racket 8.15 CS, macOS.

7.3.1. Install and test

git clone https://github.com/quasarbright/treason && cd treason
raco pkg install --auto --batch      # 16 s; installs rackcheck as a dependency
raco test reader-tests.rkt lang-tests.rkt lsp-tests.rkt
reader-tests.rkt   20 tests passed
lang-tests.rkt     31 tests passed
lsp-tests.rkt     173 tests passed

The install also places treason-language-server in Racket's user bin directory.

7.3.2. A broken macro use

A one-clause macro whose right-hand side and body are annotated as expressions:

#lang treason
(define-syntax my-let
  (syntax-rules () [(_ x rhs:expr body:expr) (let ([x rhs]) body)]))
(define total 10)
(my-let n (+ total 1) (* n 2))

Run with racket good.tsn, it prints 22. Then drop the body from the macro use and add an unrelated error:

#lang treason
(define-syntax my-let
  (syntax-rules () [(_ x rhs:expr body:expr) (let ([x rhs]) body)]))
(define total 10)
(my-let n (+ total 1))
(define also-bad unbound-name)
$ racket broken.tsn
treason: 2 errors
  5:1: my-let: no pattern matched
  6:18: unbound-name: unbound identifier

Both errors at once. Racket's expander would stop at the first.

7.3.3. What still answers inside the broken use

The language server can be driven in-process, the way the project's own lsp-tests.rkt does: open the document through server% and send it LSP requests. Three queries on total inside the my-let use, against three versions of the program. Positions are zero-based, counted from the line after #lang.

well-formed use, annotated (rhs:expr body:expr)
  goto-definition on `total` inside the use => definition at line 2, chars 8-13
  find-references on the definition         => the use at line 3, chars 13-18
  autocomplete at `total` inside the use    => ("my-let" "total")
broken use (body missing), annotated
  diagnostic: unbound-name: unbound identifier
  diagnostic: my-let: no pattern matched
  goto-definition on `total` inside the use => definition at line 2, chars 8-13
  find-references on the definition         => the use at line 3, chars 13-18
  autocomplete at `total` inside the use    => ("also-bad" "my-let" "total")
broken use (body missing), NOT annotated (rhs body)
  diagnostic: my-let: no pattern matched
  diagnostic: unbound-name: unbound identifier
  goto-definition on `total` inside the use => ()
  find-references on the definition         => ()
  autocomplete at `total` inside the use    => ()

With the annotations, all three services work inside a macro use that matched no clause. Without them, all three go silent. The annotation is the whole difference, which is the talk's claim.

7.3.4. How it decides what to expand

All in expander.rkt:

Lines 39–40 and 724–781
(~var x expr) and its shorthand x:expr are a pattern form that syntax-rules does not have. annotated-pvar is a match expander that recognises both.
Lines 993–1018, match-pattern
an annotated pattern variable always matches, binds like an ordinary one, and also records the syntax it matched in the result's ose-stxs list (ose is optimistic subexpression expansion). An unknown syntax class binds but records nothing. A plain pattern variable records nothing.
Line 1056 onward
on a pair, the matcher recurses into both sides even when the first fails, so every annotated subexpression in the use is collected, not only those before the failure.
Lines 919–953, try-patterns
if no clause matches, it ranks clauses by how far matching got (progress<?, lines 956–979), keeps the clauses tied for furthest, and takes the intersection of their annotated subexpressions. It raises an ose-error carrying those subexpressions.
Line 396
in an expression context the catcher expands them at once, because every binding is already known.
Lines 570–600
in a definition context they are held until pass 2, when every binding in the context is known, and expanded then.

So the decision is: expand only what the macro's author marked as an expression, from the clause or clauses that got furthest, and only once the scope is complete. The talk script (racketcon/script.md, line 138) names the failure mode: if an argument is missing, positions shift and the matcher may treat the wrong subform as the expression.

7.3.5. Relation to syntax/parse and syntax-spec

syntax/parse (Culpepper and Felleisen, Fortifying Macros, ICFP 2010)

the x:expr notation is syntax/parse's syntax-class annotation. In syntax/parse the class drives error messages; in Treason it also tells the expander which subforms are expressions it can expand on its own. The talk script (line

  1. says you have to annotate the same way in syntax/parse to get good

errors.

syntax-spec (Ballantyne, Gamburg and Hemann, ICFP 2024)
Treason only knows one syntax class, expr. The talk ends (script, lines 152–170) on syntax-spec as the way to say more: a grammar for the macro's own nonterminals, such as patterns, and its binding rules, which would let the same recovery work inside a pattern language. The slides credit Michael Ballantyne as co-developer (racketcon/slides.rkt, line 94).

The papers' URLs and the syntax-spec author list are from the program survey above (search only), not opened here.

8. Destructuring maps: Racket has it, Guile does not

Not a talk on this year's program. It is here because Clojure 1.13's map destructuring was the subject of the Clojure/conj keynote this week, and the comparison with Racket turns up a gap in Guile.

Racket's match destructures hash tables, with defaults, a rest binding and an explicit closed mode:

#lang racket
(define order (hash 'id 7 'role 'admin))

(match order [(hash* ['id id] ['name name #:default "anon"] #:rest rest)
              (list id name rest)])
;;=> (7 anon #hash((role . admin)))

(match order [(hash* ['id id] #:closed) id])
;; no match: 'role is present and the pattern is closed

Guile's (ice-9 match) has no hash-table pattern. An association list matches only structurally, so key order matters:

(use-modules (ice-9 match))

(match '((id . 7) (role . admin)) ((('id . id) . rest) (list id rest)))
;;=> (7 ((role . admin)))

(match '((role . admin) (id . 7)) ((('id . id) . rest) id))
;; no match: order matters

(define table (make-hash-table))
(hash-set! table 'id 7)
(match table (_ 'only-wildcard))
;;=> only-wildcard
Feature Clojure 1.13 Racket match Guile (ice-9 match)
Bind by key from a map :keys hash*, hash-table no
Default for an absent key :or #:default no
Absent key is an error :keys! the default: no match no
The unmentioned entries, as data :excess #:rest no
Reject unmentioned entries not offered #:closed no
Absent keys collected as data :missing no no

The Clojure column is from running 1.13.0-alpha8; the Racket and Guile columns are from the runs above. Racket offers the closed mode Clojure declined to. Neither Racket nor Guile reports what was missing as a value.

That gap is a project: a Guile library giving match keyed patterns over hash tables and association lists, with defaults and a rest binding as in Racket, and with the missing-keys-as-data idea from Clojure. It would be a paper for the Scheme Workshop: what each design chose, and which choices survive on a Scheme with mutable hash tables and no persistent maps.

10. Notes

  • TBD, after the stream.