Tomorrow’s Tech, Today: Innovation That Moves Us Forward
- Lisp pioneered garbage collection, first-class functions, the REPL, expression conditionals, and homoiconicity.
- Scheme evolved into PLT Scheme and became Racket, a toolkit for language-oriented programming and rapid language creation.
- Today, production use includes Clojure, Common Lisp, Emacs Lisp, Guile, and a vibrant Racket community.
- Install from racket-lang.org, use DrRacket, start files with #lang racket, or run the racket REPL.
- Lists are fundamental; the quote operator prevents evaluation, eval runs lists as code, enabling true macros and language extension.
“Lisp is worth learning for the profound enlightenment experience you will have when you finally get it.” — Eric S. Raymond
Welcome to one of programming’s oldest and most unusual families. Today, you’ll learn a language where code is data, where parentheses are pure structure, and where programs can write programs. By the end of this journey, you’ll have written your own syntax.
A Brief History: From McCarthy to Modern Day
Lisp was born in 1958, invented by John McCarthy at MIT. For context: it’s the second-oldest high-level language still in use (only Fortran, from 1957, beats it by a year). Python arrived in 1991. JavaScript in 1995. Lisp predates them by more than 30 years and several ideas we now consider “modern” were born there:
- Garbage collection — invented specifically for Lisp
- First-class functions — passing functions as arguments, now standard everywhere
- The REPL — the interactive read-eval-print loop that Python, Node, and Julia all have today started in Lisp
- Conditionals as expressions — the
ifthat returns a value - Homoiconicity — code is a data structure of the language itself
For decades, Lisp was the language of artificial intelligence. In the 70s and 80s, there were physical computers designed to run Lisp directly: the Lisp Machines built by Symbolics and LMI. Then came the “AI winter,” funding dried up, and Lisp went from star to cult language.
But interesting ideas don’t die — they mutate. That’s part of the beauty of the Lisps.
The Evolution: Scheme to Racket
In 1975, Gerald Sussman and Guy Steele created Scheme: a minimalist, elegant, almost mathematical Lisp. Scheme became academia’s favorite language for teaching programming. The legendary book “Structure and Interpretation of Computer Programs” (SICP) is written in Scheme.
In 1995, Matthias Felleisen’s group created PLT Scheme, a Scheme designed for education and programming language research. In 2010, it was renamed Racket, and today it’s much more than a Scheme: it’s a language for building languages. Its unofficial motto is “language-oriented programming”: if your problem needs its own language, Racket lets you build one in an afternoon.
Who Uses Lisp Today?
More people than you might think:
- Clojure runs in production at banks, airlines, and startups. Nubank, the largest digital bank in Latin America, runs on Clojure.
- Common Lisp (with the SBCL compiler) is still alive in expert systems, flight planning (ITA Software, acquired by Google, powered Google Flights), and scientific computing.
- Emacs Lisp — millions of people run Lisp every day without knowing it, because their editor is a Lisp interpreter.
- Guile/Guix — an entire Linux distribution configured 100% in Scheme.
- Racket has its own annual conference (RacketCon), an active academic and artistic community, and is used for language research, formal verification (Rosette), typography and publishing (Pollen), and education around the world.
- New Lisps keep appearing: Fennel (a Lisp that compiles to Lua, popular for games), Janet, Hy (a Lisp on top of Python)…
Even pop culture has caught on. In “The Amazing Digital Circus” (episode 8), when Kinger opens the terminal to reset Caine, you can see that Caine (a creative AI built in 1996) is programmed in Lisp. The file is literally named Caine-core.lisp.
Getting Started: Installation (5 Minutes)
- Go to https://racket-lang.org
- Download the installer for your system (Linux, macOS, Windows)
- Open DrRacket, the environment that comes included
DrRacket has two areas: at the top you write your definitions (your program), and at the bottom you have the REPL for live experimentation. On the first line of the definitions area, write:
#lang racket
That line tells Racket which language you’re using (remember: Racket is a language factory, so you have to pick one).
If you prefer the terminal: the racket command gives you a REPL, and raco is the package manager and tooling command.
First Contact: Everything is an Expression
In the REPL, try:
> (+ 1 2)
3
> (* 3 (+ 2 2))
12
> (string-append "hello " "world")
"hello world"
The rule of Lisp fits in one line:
Everything is
(operator argument1 argument2 ...). Always. No exceptions.
There’s no operator precedence to memorize, no special syntax for anything. (+ 1 2) adds. (if ...) decides. (define ...) names. The parentheses that look intimidating at first are actually the complete absence of arbitrary rules. After a week, you stop seeing them.
Definitions and Functions
#lang racket
(define pi-approx 3.14159)
(define (circle-area r)
(* pi-approx r r))
(circle-area 2) ; => 12.56636
definewith a name creates a constantdefinewith(name arguments...)creates a function- Comments start with
;
Anonymous functions use lambda (yes, that lambda from Church’s lambda calculus from the 1930s is the theoretical grandparent of all this):
(lambda (x) (* x x)) ; a function with no name
((lambda (x) (* x x)) 5) ; => 25, applied directly
Lists: The Heart of Lisp
Lisp stands for LISt Processing. Lists are the fundamental structure:
(list 1 2 3) ; => '(1 2 3)
'(1 2 3) ; the same thing, "quoted"
(first '(1 2 3)) ; => 1
(rest '(1 2 3)) ; => '(2 3)
(cons 0 '(1 2 3)) ; => '(0 1 2 3)
(length '(a b c)) ; => 3
Notice the quote mark '. It tells Racket: don’t evaluate this, it’s data. Hold onto that detail — it’s the door to the final trick.
Higher-Order Functions
This is where Racket shines. Passing functions to other functions is the most natural thing in the world:
(map (lambda (x) (* x x)) '(1 2 3 4 5))
; => '(1 4 9 16 25)
(filter even? '(1 2 3 4 5 6))
; => '(2 4 6)
(foldl + 0 '(1 2 3 4 5))
; => 15
map transforms, filter selects, foldl accumulates. With those three functions you can solve most list problems without writing a single for loop.
Recursion: Thinking in Spirals
In Lisp you don’t think “repeat N times” — you think “what’s the base case, and how do I move toward it?”:
(define (factorial n)
(if (= n 0)
1
(* n (factorial (- n 1)))))
(factorial 5) ; => 120
And to make things visual, let’s draw something. Racket ships with graphics libraries included:
#lang racket
(require 2htdp/image)
(define (sierpinski level)
(if (= level 0)
(triangle 8 "solid" "purple")
(let ([t (sierpinski (- level 1))])
(above t (beside t t)))))
(sierpinski 6)
Paste it into DrRacket, press Run, and watch the Sierpinski triangle appear on your screen.
The Grand Finale: Code That Writes Code
Remember the quote mark ': it turns code into data. Watch:
'(+ 1 2) ; => the LIST (+ 1 2), not the number 3
(first '(+ 1 2)) ; => the symbol +
(eval '(+ 1 2)) ; => 3. You just evaluated data as code.
Your program is a list. You can build lists. Therefore: you can build programs with programs. This is homoiconicity, and it’s why Lisp has real macros — not text macros like in C, but functions that receive code and return code, before anything runs.
Racket doesn’t have a while loop? Let’s invent one:
(define-syntax-rule (while condition body ...)
(let loop ()
(when condition
body ...
(loop))))
(define counter 0)
(while (
In case you have found a mistake in the text, please send a message to the author by selecting the mistake and pressing Ctrl-Enter.
Read the full article on the original site


