Paul Graham on programming, 17 essays in 18 minutes
CCarouseon October 3, 202621 min. read
Before Y Combinator, Paul Graham was a Lisp hacker with strong opinions about what makes a programming language powerful. Here are seventeen of his essays on languages, design, and hacking as carousels: the core argument first, the whole set in about 18 minutes, with a link to the full essay under each.
Before Y Combinator, Paul Graham built Viaweb in Lisp and wrote a run of essays arguing that programming languages are not interchangeable: some are simply more powerful, and that difference decides how fast you ship and how small your team can be. The essays range from the roots of Lisp to spam filtering to what code might look like in a hundred years. Below is a set of them as carousels: the argument up front, readable in seconds, with a link to the full piece under each.
Revenge of the Nerds
Programming languages differ sharply in power, and that difference can decide software speed, team size, and who wins. Lisp is presented as a long-standing upper bound that mainstream languages have spent decades slowly catching up to.
Revenge of the Nerds
paulgraham.com
Technology
22 min read → 75 sec
Programming languages differ sharply in power, and that difference can decide software speed, team size, and competitive outcomes. Lisp is presented as a long-standing upper bound that mainstream languages have gradually approached.
Using the most powerful language available creates durable competitive advantage in software
Lisp's extra power matters most on hard, competitive problems
02 / 17
003
Programming languages are not equivalent, and some are better for certain problems
If languages were equivalent, there would have been no reason to replace C++ with Java
03 / 17
004
Mainstream languages in 2002 were still catching up to ideas Lisp had in 1958
Java, Perl, and Python form a sequence that becomes progressively more like Lisp
04 / 17
005
Lisp and Fortran began as separate trees, one from math and one from machine architecture
Lisp stayed relevant because it came from math, and math does not get stale
05 / 17
006
Lisp introduced nine ideas, and two remain distinctive: code as data and macros
06 / 17
007
Macros let programmers write programs that write programs, from abbreviations to whole new languages
07 / 17
008
More powerful languages produce shorter programs, and shorter programs take proportionally less time to write
08 / 17
Code size advantage
7-10x
Reported Lisp versus C code-size ratios
ITA cited 20 lines of C per Lisp line
09 / 17
010
ITA's 200,000 line Common Lisp fare search system beat Travelocity and Expedia by searching many orders of magnitude more possibilities
10 / 17
011
For product-sized projects with several hackers and at least six months of work, language power outweighs library convenience
11 / 17
012
Server-based software reduces pressure to use middle-of-the-road languages and enables newer ones
12 / 17
013
Managers often choose standard languages to avoid blame, even when that makes teams slower
13 / 17
014
Hiring is a weaker objection than managers think, because strong software teams should stay under ten people
14 / 17
015
Viaweb's Lisp choice worried some investors, but without Lisp it could not have built the product buyers wanted
15 / 17
Greenspun's Tenth Rule says sufficiently complex C or Fortran programs reimplement half of Common Lisp badly
A more powerful language can be a startup’s secret weapon. Viaweb used Lisp to ship faster and outbuild competitors who were stuck with slower-moving mainstream tools, exploiting the fact that most programmers work in the average language.
Beating the Averages
paulgraham.com
Startups
19 min read → 70 sec
A case for using more powerful programming languages in startups, built around Viaweb's use of Lisp to ship faster, outbuild competitors, and exploit the slow-moving habits of mainstream programmers.
Lisp gave Viaweb a real competitive edge over 20 to 30 rivals
Faster development, lower costs, features competitors could not match
02 / 19
Viaweb, started in summer 1995, let end users build online stores through Web pages
It was, as far as he knew, the first Web-based application
03 / 19
Startups that do what average startups do should expect to fail
Startup survival is well below 50%
04 / 19
Server-based software lets startups choose any language, so the best choice is the most powerful one
05 / 19
A startup should ignore what other companies use and choose technology only by what works best
06 / 19
Web applications magnify rapid development because you can release software the minute it is done
07 / 19
Viaweb could sometimes copy a competitor's announced feature within a day or two
08 / 19
20 to 25%
of the Viaweb editor source code was macros
09 / 19
Lisp macros matter because Lisp code is made of traversable data structures that programs can rewrite
10 / 19
Viaweb had about 20 to 30 competitors, but none of their software could compete with it
11 / 19
Customers cared that Viaweb worked well, not that it was written in Lisp
12 / 19
Viaweb grew rapidly from 1996 to Yahoo's purchase
01
About 70 stores in 1996
02
500 stores in 1997
03
1070 stores by Yahoo's purchase
13 / 19
Programming languages differ in practical power, even if they are all Turing equivalent
14 / 19
For application software, using anything but the most powerful reasonably efficient language is usually a mistake
15 / 19
Programmers using weaker languages can see what they lack below them, but not what they miss above them
This is the Blub paradox
16 / 19
Programming practice often lags hardware by 10 to 20 years because languages are habits of mind
17 / 19
Competitor job listings reveal technical strength. Oracle was safest, Perl or Python was scarier, Lisp was most dangerous
A language’s power is largely its ability to make programs smaller. Succinctness helps you think, abstract, and solve problems far more than line-by-line readability does.
Succinctness is Power
paulgraham.com
Technology
12 min read → 70 sec
An argument that programming language power is largely the ability to make programs smaller, with succinctness improving speed, abstraction, and problem solving more than line-by-line readability does.
A programming language's power is mostly how succinct it lets you make programs
High-level languages exist to express in 10 lines what machine language needs 1000 for
02 / 13
Program size is better measured by syntax-tree elements than by lines or characters
The number of syntax-tree elements tracks the parts a programmer must hold in mind
03 / 13
More succinct languages let programmers build software faster because output per day stays roughly similar
A language that feels restrictive is usually forcing a longer route, which means insufficient succinctness
04 / 13
Succinctness is a useful design test because shorter programs usually signal a better abstraction
05 / 13
Designing languages disproves the claim that all languages are equivalent, because each feature changes what programs cost
06 / 13
Ericsson field report
4–10×
Erlang was more succinct than C++, with proportionately faster development
07 / 13
Small predefined benchmark problems underestimate powerful languages because they miss discovery and problem finding
The real test of a language is how well it helps you discover and solve new problems
08 / 13
Languages known for succinctness, like Forth, Joy, and Icon, are good places to find abstractions
09 / 13
Readability should be judged at the whole-program level, not by how easy one line looks
Per-line readability can be a marketing advantage while still increasing total reading effort
10 / 13
Mathematical notation is hard because the ideas are hard. Prose would only make them longer
Individual programs can be too dense, but that does not show a language itself is too succinct
11 / 13
Field reports are less precise than studies, but often more accurate about language power
Lisp broke from Fortran by introducing nine ideas, from conditionals and recursion to macros and runtime compilation. Later languages adopted the early ones, while Lisp’s code-as-tree model still sets it apart.
What Made Lisp Different
paulgraham.com
Technology
3 min read → 55 sec
Lisp differed from Fortran by introducing nine ideas, from conditionals and recursion to macros and runtime compilation. Many later languages adopted the first set of ideas, while Lisp's code-as-tree model remains distinctive.
Lisp introduced nine ideas that reshaped programming.
Conditionals, first-class functions, recursion, and garbage collection spread widely. Tree syntax and read-compile-run unity mostly stayed Lisp's.
02 / 18
McCarthy invented conditionals while developing Lisp.
He then got them into Algol and later languages.
03 / 18
Fortran had only a conditional goto.
It closely modeled hardware branch instructions.
04 / 18
Lisp treated functions as a data type.
Functions had literals, variables, and argument passing.
05 / 18
Lisp was the first programming language to support recursion.
06 / 18
In Lisp, values have types.
Variables effectively hold pointers to values.
07 / 18
Fortran split expressions from statements.
Its punched-card, line-oriented form could not nest statements.
08 / 18
Block-structured languages removed that limit.
Fortran and Algol had already entrenched the expression-statement split.
09 / 18
Lisp made programs fully composable.
Its code trees are expressions that always return values.
10 / 18
When everything is an expression, conditionals and assignments compose in either direction.
11 / 18
Symbols are not strings.
Symbol equality can be tested by comparing a pointer.
12 / 18
Running code at compile-time enables macros.
Compiling at runtime enables extension languages like Emacs.
13 / 18
Reading at runtime lets programs communicate with s-expressions.
That idea was later reinvented as XML.
14 / 18
These Lisp ideas are now widespread.
01
Conditionals spread widely.
02
First-class functions spread widely.
03
Recursion spread widely.
04
Pointer-like variables spread widely.
05
Garbage collection spread widely.
15 / 18
Expression-only programs are entering the mainstream.
16 / 18
Tree syntax and read-compile-run unity remain largely unique to Lisp.
John McCarthy’s 1960 discovery was that a whole programming language can be built from a tiny core. That self-describing design is why Lisp has shaped so much of how later languages evolved.
The Roots of Lisp
paulgraham.com
Technology
2 min read → 35 sec
A short essay on John McCarthy's 1960 discovery that a programming language can be built from a small core, and why Lisp's self-describing design has shaped later language development.
John McCarthy showed in 1960 that a whole language can be built from a few simple operators.
Lisp's defining quality is that it can be written in itself.
02 / 13
McCarthy's 1960 paper did for programming something like what Euclid did for geometry.
03 / 13
Lisp means "List Processing."
Lisp uses lists for both code and data.
04 / 13
Lisp has a semantic core, which is why it has dialects unlike other languages.
05 / 13
Lisp's defining quality is that it can be written in itself.
06 / 13
Programming has had two clean models so far, the C model and the Lisp model.
07 / 13
The C model and the Lisp model are points of high ground, with swampy lowlands between them.
08 / 13
New languages moved toward the Lisp model by adding Lisp features piecemeal.
01
They started with the C model.
02
They added runtime typing.
03
They added garbage collection.
09 / 13
A common recipe in the past 20 years was to start with the C model and add Lisp features piecemeal.
10 / 13
Understanding McCarthy's result helps explain where programming languages are heading.
11 / 13
Retracing McCarthy's steps in running Common Lisp code shows what he discovered in simple terms.
Lisp works best when you extend the language to fit the problem rather than the other way around. This bottom-up style produces smaller programs, more reuse, and real leverage for small teams.
Programming Bottom-Up
paulgraham.com
Technology
4 min read → 50 sec
A 1993 essay argues that Lisp programming works best by extending the language to fit the problem. This bottom-up style produces smaller programs, more reuse, and higher leverage for small teams.
Bottom-up design builds the language up toward the program, not just the program down
In Lisp, language and program evolve together until code fits the problem's natural structure
2 / 15
Top-down design divides a program into nested subroutines until each part is understandable as one unit
3 / 15
Large program components hide errors and make software harder to read, test, and debug
4 / 15
Programmers can add a missing operator, then reuse it to simplify other parts of the program
5 / 15
When the language does more work, less code remains after bookkeeping is abstracted away
6 / 15
Shorter programs need fewer divisions, which makes them easier to read and modify
7 / 15
Bottom-up design makes programs smaller, clearer, and less error-prone by reducing components and connections
8 / 15
Fewer components create fewer connections between components, which lowers the chance of errors
9 / 15
General-purpose operators are easier to read than many special-purpose subroutines
10 / 15
Working bottom-up exposes repeated patterns and can lead to simpler redesigns
11 / 15
Bottom-up design promotes reuse, so a large utility base cuts effort on later programs
12 / 15
Other languages allow bottom-up design through libraries, but Lisp gives much broader power to extend the language
13 / 15
Lisp makes bottom-up design central enough that it becomes a different way of programming
Looking a century out, the languages that last will have small cores and flexible semantics, with optimization bolted on later. As hardware keeps getting faster, programmer time becomes the truly scarce resource.
The Hundred-Year Language
paulgraham.com
Technology
20 min read → 70 sec
An essay on what programming languages may look like in 100 years, arguing that small cores, flexible semantics, and optimization added later will outlast efficiency-first designs. It predicts faster hardware will make programmer time the real scarce resource.
A usable hundred-year language could be designed now
Lisp already designed much of its core in 1958
2 / 18
Programming languages evolve slowly because they are notation, more like mathematical notation than transportation technology
3 / 18
Languages will evolve in branching trees. Java will likely be an evolutionary dead-end like Cobol.
The strongest long-term languages will have small, clean cores with few fundamental operators
4 / 18
If Moore's Law continued for 100 years
74 quintillion×
faster computers would be
5 / 18
Most extra computing power will be wasted, because each generation spends gains on simpler, more wasteful designs
6 / 18
Good waste spends more resources to get simpler designs. Bad waste solves the wrong problem.
Faster hardware will make programmer time more valuable than machine time
7 / 18
Separate string types are premature optimization. Strings are semantically a subset of lists.
Arc dropped strings, and recursive functions handled some tasks more easily than regular expressions
8 / 18
Future languages may flatten data structures further, possibly treating arrays, hash tables, and numbers as optimizations
9 / 18
Future languages should separate program meaning from implementation, with optimization advice added later
10 / 18
10×
speed cost per interpretation layer
Layered systems buy flexibility and easier change
11 / 18
Bottom-up programming builds layers that act as languages, producing smaller, more flexible, more reusable software
12 / 18
Object-oriented programming persists because large organizations can accrete patches with it, not because it ensures reuse
13 / 18
Parallelism will usually stay optional and late-stage, except in special applications where optimization demands it
14 / 18
Profilers will matter more than faster compilers, because they guide programs from acceptable to maximal performance
15 / 18
Open-source languages like Perl, Python, and Ruby show language design shifting from researchers to working hackers
16 / 18
Static typing blocks true macros, and without macros no language is worth using
You can understand a language by the specific weakness it corrected in the one before it. The whole family tree reads as a chain of fixes: more control, safer syntax, richer types, objects, arrays, accessibility.
What Languages Fix
paulgraham.com
Technology
1 min read → 35 sec
Programming languages can be understood by the specific weakness they corrected in earlier languages. The piece maps language families as chains of fixes, from lower-level control to safer syntax, richer types, objects, arrays, and accessibility.
Programming languages make sense as fixes for earlier languages.
A language's niche is the gap it first filled for early users.
02 / 11
003
Many languages spread by fixing what earlier languages lacked.
They felt less scary, less kludgy, or more capable.
03 / 11
004
Language lineages often form chains of fixes.
Assembly led to Fortran, C, C++, and Java.
04 / 11
Assembly was too low-level for several successors.
INDEX
001
Fortran fixed that.
002
Algol fixed that.
003
C fixed that.
05 / 11
Algol and Fortran lacked enough data types.
INDEX
001
Pascal fixed that.
002
PL/1 fixed that.
06 / 11
Some languages fixed narrow technical limits.
INDEX
001
Modula fixed Pascal for systems programming.
002
Simula fixed Algol for simulations.
003
APL fixed Fortran for array manipulation.
07 / 11
Later fixes kept narrowing the gap.
INDEX
001
Smalltalk fixed Simula by making everything an object.
002
J fixed APL requiring its own character set.
08 / 11
One chain runs through C, C++, Java, and C#.
INDEX
001
C++ fixed C being too low-level.
002
Java fixed C++ being a kludge.
003
C# fixed Java being controlled by Sun.
09 / 11
010
Basic, Cobol, Javascript, and Python spread by feeling less scary than earlier languages.
Languages should be designed for humans: strong programmer control, brevity, and real applications driving the features. Graham also predicts server-based software will reshape which languages win.
Five Questions about Language Design
paulgraham.com
Technology
12 min read → 70 sec
Notes on programming language design argue for human-centered languages, strong programmer control, brevity, and real applications driving features. They also predict server-based software will reshape language choices and priorities.
Programming languages should fit human limits, their job is helping people think
The best languages are built for expert programmers, not weaker ones
02 — 20
Good programmers write a disproportionately large percentage of software
Designing for them matters most
03 — 20
Good languages give programmers maximum control
Lisp does this by letting users extend the language itself
04 — 20
Languages that prevent unsafe actions often talk down to programmers instead of treating them as equals
05 — 20
Mathematical elegance matters only when it makes programs easier to understand
06 — 20
Brevity is a core virtue in language design
Shorter programs and thinner manuals usually mean better design
07 — 20
Brevity comes from four sources
01
Many library functions
02
Implicit defaults
03
Terse syntax
04
Short names
08 — 20
Shorter manuals often come from removing special cases that needed long explanations
09 — 20
Large libraries become harmful when finding a function takes longer than writing it yourself
Libraries should be organized so programmers can guess which call does the right thing
10 — 20
Lisp may be unpopular partly because prefix syntax feels unfamiliar
Though that remains unresolved
11 — 20
Hacking is closer to architecture than science
The goal is great programs, not publishable ideas
12 — 20
The best languages usually evolve alongside real applications
C for systems, Lisp for symbolic differentiation
13 — 20
A language must be good for throwaway programs
Many serious programs start that way
14 — 20
Server-based software changes language design fundamentally
15 — 20
Server-based apps need languages built for constant change
As many as five or ten releases a day
16 — 20
Any language can be used for server-based apps, rapid releases matter more than language choice
17 — 20
Continuations may help Web software simulate subroutines in the stateless world of Web sessions
18 — 20
Speed in practice comes more from good profilers than from compiler optimizations
Language design is a user-centered design problem, not a research problem. Design around human needs, iterate with prototypes, and keep it under the control of one person with taste.
Design and Research
paulgraham.com
Technology
11 min read → 45 sec
Programming language design is framed as a user-centered design problem rather than a research problem. The piece argues for designing around human needs, iterative prototypes, and single-person control.
Design aims for what is good, research aims for what is new
Programming language design should start from user needs, not user requests or theory
02 / 12
003
Good design depends on a specific user, and works best when the designer is that user
Good or bad design cannot be judged without naming the intended user group
03 / 12
004
C, Lisp, and Smalltalk were built for their designers
Cobol, Ada, and Java were built for others
04 / 12
005
Users are the measure of design quality, but they often misread what they actually need
05 / 12
006
Designing for users you see as less sophisticated tends to corrupt the design
06 / 12
007
A language should be judged by how cleanly programs are developed, not just finished code
Shorter finished programs can mislead, because elegant output can hide an ugly development process
07 / 12
008
Programming languages are for humans, and human limits on detail shape what makes them usable
08 / 12
009
An interactive toplevel is a huge win, and mandatory type declarations work poorly with it
09 / 12
010
Good design needs constant contact with users, so prototypes should reach them as early as possible
10 / 12
011
Good design usually needs one person in control, because design by committee produces bad design
A language becomes popular by first winning over expert hackers, then spreading through tools, systems, and time. The strongest ones are terse, hackable, interactive, and built around powerful libraries and real applications.
Being Popular
paulgraham.com
Technology
32 min read → 70 sec
Programming language popularity follows what expert hackers adopt, then spreads through tools, systems, and time. The strongest languages are terse, hackable, interactive, and built around powerful libraries and real applications.
Programming languages become popular when expert hackers choose them and others follow
A popular language needs four basics: a free implementation, a book, something to hack, and time
02 — 19
Legacy software like Cobol and hype like Ada and Java affect popularity, but less over the long term
03 — 19
A language has to stay popular to stay good, because real users drive improvements
04 — 19
Hackers prefer languages that are:
01
Terse
02
Interactive
03
Hackable
04
Rich in orthogonal libraries
05 — 19
Strong typing hurts brevity because programmers must write declarations before programs
06 — 19
Good languages let programmers break abstractions and access internals when needed
07 — 19
Classic macros are powerful because they allow arbitrary source transformations with simple rules
Hygienic macros block some useful cases, because variable capture is sometimes exactly what macros need
08 — 19
Great libraries matter more than type systems, object orientation, or functional purity
09 — 19
A good profiler improves real program speed more than a compiler that only generates fast code
10 — 19
Languages win big systems by being good for throwaway programs, because big programs often start small
11 — 19
Perl became popular before Perl 5 was suitable for serious programs, because it excelled at throwaway scripts
12 — 19
Languages usually become popular as the scripting language of a popular system
13 — 19
20
independent users is enough to make a new language real
14 — 19
The best way to reach the first twenty users is a trojan horse application
15 — 19
Physical books still matter because bookstores help hackers discover new languages
16 — 19
Common Lisp is unpopular partly because it is an orphan and a bad Unix scripting language
17 — 19
A new Lisp could become popular by serving server-based applications better than Perl or Python
Language popularity follows familiarity, ecosystem, and hiring incentives more than technical merit. Lisp stays uncommon partly because it looks foreign, not because it is slow or no better than the mainstream.
If Lisp is So Great
paulgraham.com
Technology
2 min read → 50 sec
Programming language popularity follows familiarity, ecosystem effects, and hiring incentives more than technical merit. Lisp remains less common partly because it looks foreign, not because it is slow or equivalent to mainstream languages.
Programming language popularity has little correlation with language quality
Lisp survives because languages are not equivalent, and some are much better
02 / 10
003
Lisp looks hard because its syntax is unlike the languages most programmers know
People avoid it by inventing reasons that mask their fear of its unfamiliar form
03 / 10
I suppose I should learn Lisp, but it seems so foreign
1983 notebook entry
04 / 10
005
The old claim that Lisp is too slow no longer holds
Modern Lisp dialects are among the faster languages
05 / 10
006
The current excuse against Lisp is circular: other languages are more popular
06 / 10
Programming language popularity is self-reinforcing through three mechanisms
INDEX
001
More libraries get written for popular languages, which makes them even more popular
002
Programs often need to work with existing programs, so languages spread from program to program
003
Managers prefer popular languages because developers are easier to replace
07 / 10
008
If programming languages were roughly equivalent, using the most popular one would make sense
08 / 10
009
Lisp survives for the same reason Jane Austen survives while John Grisham outsells her
Less popular languages persist because some are much better
Much of object-oriented programming’s appeal comes from language limits, corporate team structure, and visible scaffolding rather than real necessity. OO fits some domains, but it is not the right shape for every program.
Why Arc Isn't Especially Object-Oriented
paulgraham.com
Technology
2 min read → 55 sec
A critique of object-oriented programming argues that its appeal often comes from language limits, corporate team structure, and visible scaffolding rather than necessity. It allows that OO fits some domains, but not every program.
Object-oriented programming should not pervade every program
Programs need new types without forcing every solution into type definitions
2 / 11
Five reasons drive object-oriented programming's appeal, and three and a half are bad
3 / 11
Object-oriented programming fits big companies by constraining large, changing teams of mediocre programmers
Big-company code accepts bloat and duplication because discipline matters more than elegance there
4 / 11
Object-oriented programming can make simple tasks look like substantial work through extra scaffolding
A Lisp hacker might push a symbol onto a list where object-oriented code needs whole class files
5 / 11
Object-oriented programming is exciting in statically typed languages without lexical closures or macros
In those languages, it partly works around missing features, as in Greenspun's Tenth Rule
6 / 11
Object-oriented abstractions map well to some domains, like simulations and CAD systems
7 / 11
Sub-concepts like overloading are not inherently tied to classes and can be offered separately
8 / 11
Common Lisp has a powerful object system, but it was never needed here, not even once
Hash tables full of closures handled problems that wimpier languages would require object-oriented techniques for
9 / 11
Designing a language from personal experience is risky, but adding features never needed is riskier
You can judge a technology by its outward signals. Hype, committee design, corporate motives, and bureaucratic appeal often predict weak technology, and hacker intuition picks up on those signals early.
Java's Cover
paulgraham.com
Technology
6 min read → 55 sec
An essay uses hacker intuition to judge Java by its outward signals, arguing that hype, committee design, corporate motives, and bureaucratic appeal often predict weak technology.
Java looked unlikely to succeed because its outward signals matched past bad technologies
Hackers must judge by signs, there are too many languages to learn them all
2 / 15
Java's strongest warning signs were hype, committee design, corporate control, and appeal to bureaucracies
3 / 15
Real standards do not need heavy promotion
C, Unix, and HTML showed this
4 / 15
Technologies pushed for ulterior motives often serve strategy more than technical merit
Java served Sun against Microsoft
5 / 15
Java was designed to stay easy for C programmers, not to push language design forward
6 / 15
Strong languages inspire love, but Java lacked the devotion seen around C, Perl, Python, Smalltalk, and Lisp
7 / 15
Many smart programmers used Java from pressure by funders, customers, or management, not free choice
8 / 15
Good programming languages usually come from small groups
Committee-designed languages have a bad record
9 / 15
Java appeared bureaucratic, with many protocols instead of getting out of the programmer's way
10 / 15
Sun presented Java as grassroots and open-source, but it remained controlled by a giant company
11 / 15
Large organizations prefer languages that limit damage by mediocre teams, while hackers want power
12 / 15
The people most captivated by Java were suits, big-company programmers, and job-seeking undergrads, not admired programmers
13 / 15
Languages built for hackers and their creators usually win, while languages built for large organizations usually lose
Bayesian filtering can identify spam from the words and headers in each message, with far fewer false positives than hand-built rules. Training the filter per user lets it adapt as spam keeps changing.
A Plan for Spam
paulgraham.com
Technology
20 min read → 80 sec
Bayesian content filtering can identify spam from the words and headers in each message, with far fewer false positives than hand-built rules. Per-user training and probability-based scoring make the filter adapt as spam changes.
Bayesian filtering stops spam better than hand-written rules
Statistical learning adapts as spam evolves and finds signals rules miss
2 / 19
A tweaked Bayesian filter misses fewer than 5 per 1000 spams, with 0 false positives
False positives are far worse than missed spam, so filters bias strongly against them
3 / 19
Per-user Bayesian filters work better because each user has distinct good and bad word patterns
4 / 19
Simple rule baseline
79.7%
Spam caught by a rule for the word "click", with 1.2% false positives
5 / 19
Hand-built feature filters get much harder on the last few percent and raise false positives
6 / 19
Statistical filtering finds unexpected spam signals like "per", "FL", and "ff0000"
Bayesian filters discover patterns rule-writers would never think to encode
7 / 19
The filter uses about 4000 spam messages and 4000 nonspam messages as training corpora
8 / 19
Token counts scan full messages, including headers, html, and javascript, not just visible text
9 / 19
The algorithm applies three adjustments to raw token counts
1
Doubles nonspam counts to bias against false positives
2
Ignores rare words that appear in too few messages
3
Assigns unseen-word probabilities of .01 and .99
10 / 19
New mail is scored from the 15 most interesting tokens, and spam is flagged above .9 probability
11 / 19
Probabilities are clearer than spam scores, because evidence combines by Bayes' Rule into explicit odds
12 / 19
Words rare in spam, like "though" or "apparently", lower spam probability as much as bad words raise it
13 / 19
Each user should train the filter with delete and delete-as-spam actions to build personal probabilities
14 / 19
Whitelists help mainly to save computation, because unknown addresses can still belong to trusted senders
15 / 19
Bayesian filters adapt as spam evolves, because spammers must still deliver recognizable messages
Spammers could evade checksum filters with mad-lib variation, but Bayesian filters force messages toward ordinary mail
16 / 19
Spam economics
15 per million
Response rate spam works on, because sending 1 million emails costs about $200
17 / 19
Filtering out 95% of spam raises the cost to reach a given audience by a factor of 20
Bayesian spam filtering works far better with email-specific signals, richer tokenization, and per-user training. The 2002 to 2003 results show high detection, low false positives, and the limits of network-level filtering.
Better Bayesian Filtering
paulgraham.com
Technology
18 min read → 65 sec
Bayesian spam filtering works far better when it uses email-specific signals, richer tokenization, and per-user training. Results from late 2002 to early 2003 show high detection, low false positives, and limits of network-level filtering.
Bayesian spam filtering reaches 99.5% detection with under .03% false positives
Smarter tokenization and email-specific signals close the gap to CRM114
02 — 16
Pantel and Lin achieved only 92% detection and 1.16% false positives from weaker design choices
They trained on just 160 spam and 466 nonspam mails, too little data
03 — 16
Spam filters should use email-specific signals, because headers, structure, and adversaries matter
Macs won hackers back once OS X paired Unix with strong hardware design. That matters beyond hackers, because mainstream computing tends to follow wherever the best developers choose to work.
Return of the Mac
paulgraham.com
Technology
4 min read → 80 sec
Macs regained appeal among hackers after OS X combined Unix with strong hardware design. Hacker platform choices shape future mainstream computing because software starts where top developers choose to work.
Hackers are switching back to Macs because OS X makes them open and good again
Platforms win software first from great hackers, then that software sells the hardware
2 / 14
Hackers matter beyond their small numbers because mainstream computing often follows them within ten years
Technologies like Unix, bitmapped displays, and the Web spread from CS departments to everyone else
3 / 14
In the mid to late 1980s, many hackers wrote software for the Mac or wanted to
4 / 14
Linux and FreeBSD pulled hackers to Intel boxes because they followed the most powerful OS
5 / 14
OS X brought hackers back by putting FreeBSD under well-designed Powerbooks
Research groups at places like MIT were buying Powerbooks, not just designers or casual users
6 / 14
New software usually starts on the machines great hackers personally use, especially for platform-defining tools
7 / 14
Many early Apple II sales came from VisiCalc, which Bricklin and Frankston wrote for Apple II because they liked it
8 / 14
In 1994, Koling built Internet voice calling to reach Taiwan cheaply, years before VoIP became big business
Hackers create technologies for themselves first, then those technologies spread
9 / 14
To attract hackers who create software that sells hardware, a platform must be open and good
01
Hackers need the freedom to modify and control their systems
02
The platform must be technically excellent and well-designed
03
Both qualities together draw the creators of breakthrough software
10 / 14
18.8%
Macintosh share at Y Combinator visitor OS tracking
Much higher than it would have been five years earlier
11 / 14
Apple's user base included a seventy year old mother and computer science PhDs, showing strength at both ends
12 / 14
Apple is strong at the low end and high end but still has a small overall market share
That split is temporary, because more people will want Macs that pair strong design with Unix
That is seventeen of Paul Graham’s essays on programming, scanned in about 18 minutes.
The through-line is that languages are tools with wildly different leverage, and that the good ones share a shape: a small core, terseness, and enough power that you extend the language toward your problem instead of contorting your problem to fit the language. Popularity lags merit because it runs on familiarity and hiring, not on what is actually best. And the way to tell good technology from bad is often to read its outward signals, the way a hacker reads a language’s syntax before writing a line.
Save the carousels you want to come back to, and when an essay earns your full attention, the link to the original is under each one. The point was never to replace the essays. It is to let you decide, in a few minutes, which ones deserve the full read.