Racket
A language for making languages.
Racket grew out of Scheme into a full programming platform. It comes with a friendly IDE (DrRacket), a huge standard library and unique tools for creating your own languages. It is widely used to teach programming through the book How to Design Programs, and for research on programming languages.
Why learn Racket?
Racket is both an excellent first language and a laboratory for building new languages and DSLs.
- Beginner-friendly: DrRacket and teaching languages guide new programmers.
- Batteries included: web server, GUI, plotting and more in the standard library.
- Language-oriented: build your own DSL with
#lang.
Set up and run your first program
Download Racket from racket-lang.org; it includes the DrRacket IDE and the raco package tool.
racket hello.rkt
raco pkg install <package>#lang racket
(define name "Ada")
(printf "Hello, AI! Welcome to Racket, ~a.\n" name)#lang line that selects the language.Values and definitions
Racket uses prefix notation: the operator comes first. define names values and functions.
#lang racket
(define layers 32)
(define model "llama3.1")
(define (fp16-gb params) (/ (* params 2) 1e9))
(printf "~a: ~a layers, ~a GB\n" model layers (fp16-gb 8.03e9))
(displayln (string-upcase model))Lists and higher-order functions
map, filter and foldl work on lists. for/list and friends give readable loops.
#lang racket
(define vram '(("H100" . 80) ("H200" . 141) ("RTX 5090" . 32)))
(displayln (map car (filter (λ (p) (>= (cdr p) 80)) vram)))
(displayln (foldl + 0 (map cdr vram)))
(displayln (for/list ([i (in-range 1 6)]) (* i i)))
(displayln (for/sum ([i (in-range 1 11)]) i))Structs and pattern matching
struct defines records. match takes data apart by shape.
#lang racket
(struct gpu (name vram) #:transparent)
(define (describe g)
(match g
[(gpu name v) #:when (>= v 80) (format "data center GPU ~a" name)]
[(gpu name v) (format "GPU ~a (~a GB)" name v)]))
(for ([g (list (gpu "H100" 80) (gpu "RTX 5090" 32))])
(displayln (describe g)))Hashes, strings and files
Hash tables store key-value data. The standard library makes reading files and processing text simple.
#lang racket
(define counts (make-hash))
(for ([w (string-split (string-downcase (file->string "notes.txt")))])
(hash-update! counts w add1 0))
(define top (take (sort (hash->list counts) > #:key cdr) 5))
(for ([p top]) (printf "~a ~a\n" (car p) (cdr p)))Macros and languages
Racket macros transform code safely (hygienically). You can build whole new languages, from teaching languages to Typed Racket.
#lang racket
(define-syntax-rule (repeat n body ...)
(for ([_ (in-range n)]) body ...))
(repeat 3 (displayln "training step"))
(define-syntax-rule (unless-zero x expr)
(if (zero? x) 'skipped expr))
(displayln (unless-zero 0 (/ 1 0))) ; skipped, no division errorAI with Racket
Racket is used to teach the foundations of AI: search algorithms, logic programming (with miniKanren), and automatic differentiation. Its plot library visualises results, and its built-in HTTP and JSON libraries make calling LLM APIs straightforward.
The essential libraries
Gradient descent from scratch
Fit y = 3x + 0.5 with lists and a fold.
#lang racket
(define xs (for/list ([i 100]) (+ -1.0 (* 2.0 (/ i 99)))))
(define ys (map (λ (x) (+ (* 3 x) 0.5)) xs))
(define n (length xs))
(define (step wb _)
(match-define (cons w b) wb)
(define errs (map (λ (x y) (- (+ (* w x) b) y)) xs ys))
(define gw (/ (* 2 (apply + (map * errs xs))) n))
(define gb (/ (* 2 (apply + errs)) n))
(cons (- w (* 0.1 gw)) (- b (* 0.1 gb))))
(displayln (foldl (λ (i wb) (step wb i)) (cons 0.0 0.0) (range 500)))Build an AI agent in Racket
The http-easy package and built-in json library let Racket run the full tool-calling loop. Tools live in a hash from name to function.
#lang racket
;; raco pkg install http-easy
(require net/http-easy json)
(define url "http://localhost:11434/v1/chat/completions")
(define tools
(list (hasheq 'type "function"
'function (hasheq 'name "get_weather" 'description "Weather for a city"
'parameters (hasheq 'type "object"
'properties (hasheq 'city (hasheq 'type "string"))
'required '("city"))))))
(define impls (hash "get_weather" (λ (args) (format "It is 24°C and sunny in ~a." (hash-ref args 'city)))))
(define (chat messages)
(define res (post url #:json (hasheq 'model "llama3.1" 'messages messages 'tools tools)))
(hash-ref (first (hash-ref (response-json res) 'choices)) 'message))
(let loop ([messages (list (hasheq 'role "user" 'content "Should I take an umbrella in Lahore today?"))]
[n 5])
(define msg (chat messages))
(define calls (hash-ref msg 'tool_calls '()))
(if (or (zero? n) (null? calls) (eq? calls 'null))
(displayln (hash-ref msg 'content))
(loop (append messages (list msg)
(for/list ([c calls])
(define f (hash-ref c 'function))
(hasheq 'role "tool" 'tool_call_id (hash-ref c 'id)
'content ((hash-ref impls (hash-ref f 'name))
(string->jsexpr (hash-ref f 'arguments))))))
(sub1 n))))Racket's JSON library uses symbols for object keys, so fields are read with hash-ref and a quoted name.
ollama pull llama3.1, and keep it running. The code talks to its OpenAI-compatible API at http://localhost:11434/v1, so the same program also works with vLLM, llama.cpp server or a cloud API by changing the URL, model name and adding an API key.Racket learning roadmap
Tick items off as you go. Your progress is saved in this browser.
Beginner
Intermediate
Advanced
Projects to build
Racket cheat sheet
| Task | Syntax |
|---|---|
| Define | (define x 5) |
| Function | (define (f x) (* x 2)) |
| Lambda | (λ (x) (* x 2)) |
| Loop | (for ([i 10]) (displayln i)) |
| Struct | (struct p (x y)) |
(printf "~a\n" x) |
Common mistakes
- Each file needs a
#langline at the top. - Lists are immutable; functions return new lists.
- Teaching languages (BSL, ISL) restrict features; switch to
#lang racketfor full power.
Where to go next
- How to Design Programs — free book
- Racket Guide — official
- Beautiful Racket — language design
On TensorCore.si: Scheme volume, Lisp volume.
Keyboard: [ previous language · ] next language · / search the library