Skip to content
Volume R · The TensorCore.si Library

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.

Prologue

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.
Prologue

Set up and run your first program

Download Racket from racket-lang.org; it includes the DrRacket IDE and the raco package tool.

terminal
racket hello.rkt
raco pkg install <package>
hello.rkt
#lang racket
(define name "Ada")
(printf "Hello, AI! Welcome to Racket, ~a.\n" name)
TipEvery file starts with a #lang line that selects the language.
Chapter 1

Values and definitions

Racket uses prefix notation: the operator comes first. define names values and functions.

basics.rkt
#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))
Chapter 2

Lists and higher-order functions

map, filter and foldl work on lists. for/list and friends give readable loops.

lists.rkt
#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))
Chapter 3

Structs and pattern matching

struct defines records. match takes data apart by shape.

structs.rkt
#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)))
Chapter 4

Hashes, strings and files

Hash tables store key-value data. The standard library makes reading files and processing text simple.

words.rkt
#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)))
Chapter 5

Macros and languages

Racket macros transform code safely (hygienically). You can build whole new languages, from teaching languages to Typed Racket.

macros.rkt
#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 error
Part II · AI with Racket

AI 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

mathMatrices, statistics and special functions.
plotCharts and 3D plots.
net/http-easySimple HTTP client.
jsonBuilt-in JSON support.

Gradient descent from scratch

Fit y = 3x + 0.5 with lists and a fold.

gradient.rkt
#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)))
Part III · Build an AI agent

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.

Your goal→Model plans→Tool call→Your code runs the tool→Result back to model→Final answer
agent.rkt
#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.

Run it locallyInstall Ollama, run 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.
Part IV · Your path

Racket learning roadmap

Tick items off as you go. Your progress is saved in this browser.

Beginner

Intermediate

Advanced

Part IV · Your path

Projects to build

Picture artDraw shapes with the 2htdp/image library.
Word gameA hangman game with a GUI.
Mini languageCreate a tiny DSL with #lang.
Reference

Racket cheat sheet

TaskSyntax
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))
Print(printf "~a\n" x)
Reference

Common mistakes

  • Each file needs a #lang line at the top.
  • Lists are immutable; functions return new lists.
  • Teaching languages (BSL, ISL) restrict features; switch to #lang racket for full power.
Reference

Where to go next

On TensorCore.si: Scheme volume, Lisp volume.

Keyboard: [ previous language · ] next language · / search the library