YUI Library
AI-assisted summary of Crockford on JavaScript - Section 8: Programming Style & Your Brain — original source. Check the original for full context.
Source published:
Key ideas
- Douglas Crockford argues that human cognitive architecture—specifically the evolutionary dominance of the fast, pattern-matching 'gut' over analytical reasoning—makes programmers inherently ill-equipped for the demand of absolute perfection in software. (2:53)
- JSLint's design philosophy establishes that syntactic forms capable of concealing defects are themselves defects, requiring automated discipline to override developers' defensive rationalizations. (57:35)
- JavaScript's automatic semicolon insertion turns seemingly aesthetic layout choices, such as placing opening braces on a new line after a return statement, into silent runtime bugs that return undefined. (18:42)
- Rather than expanding the language with complex features or adopting Java-like alternatives like Google Dart, Crockford advocates aggressively subsetting JavaScript around its foundational strengths: Scheme-style functions and Self-style prototypes. (63:08)
Detailed notes
## Background Published by the YUI Library channel on YouTube on November 13, 2011, this video captures Douglas Crockford's keynote address at YUIConf 2011 held at Yahoo!'s Great America campus in Santa Clara. According to the show description, Crockford draws on cognitive science to explore why disciplined code style is vital in software engineering—especially in JavaScript—and explains how static analysis tools like JSLint enforce reliability.
## TL;DR Douglas Crockford explores the neurological mismatch between prehistoric human instincts and the rigorous demand for perfection in software development. Drawing on cognitive concepts like System 1 ('the gut') and System 2 ('the head'), he illustrates how programmers routinely misjudge risks and fall prey to cognitive blind spots. He walks through historical design flaws inherited from languages like B, C, and early JavaScript, showing how ambiguous syntax, automatic semicolon insertion, switch fall-throughs, and dynamic scoping breed subtle, catastrophic bugs. Ultimately, Crockford advocates for disciplined subsetting of JavaScript and the strict adoption of error-resistant conventions enforced by JSLint to protect developers from their own evolutionary shortcomings.
## Atmosphere & style The presentation carries Crockford's trademark dry, acerbic wit and philosophical gravity, balancing cerebral cognitive theory with pragmatic developer advice. Speaking with measured deadpan cadence, he alternates between self-deprecating confessions of his own programming fallibility and biting critiques of flawed language features and fragile programmer egos. The audience responds with frequent chuckles and knowing laughs as Crockford demystifies industry dogma, transforming an ostensibly dry lecture on formatting and linters into a sharp, entertaining reflection on human psychology and software craftsmanship.
## Bulletin - [02:53](https://www.youtube.com/watch?v=taaEzHI9xyY&t=173s) Douglas Crockford argues that human cognitive architecture—specifically the evolutionary dominance of the fast, pattern-matching 'gut' over analytical reasoning—makes programmers inherently ill-equipped for the demand of absolute perfection in software. - [57:35](https://www.youtube.com/watch?v=taaEzHI9xyY&t=3455s) JSLint's design philosophy establishes that syntactic forms capable of concealing defects are themselves defects, requiring automated discipline to override developers' defensive rationalizations. - [18:42](https://www.youtube.com/watch?v=taaEzHI9xyY&t=1122s) JavaScript's automatic semicolon insertion turns seemingly aesthetic layout choices, such as placing opening braces on a new line after a return statement, into silent runtime bugs that return undefined. - [01:03:08](https://www.youtube.com/watch?v=taaEzHI9xyY&t=3788s) Rather than expanding the language with complex features or adopting Java-like alternatives like Google Dart, Crockford advocates aggressively subsetting JavaScript around its foundational strengths: Scheme-style functions and Self-style prototypes.
## Key takeaways - [02:53](https://www.youtube.com/watch?v=taaEzHI9xyY&t=173s) The human brain relies on two cognitive modules: System 1 (the gut), which prioritizes fast survival pattern-matching over accuracy, and System 2 (the head), which rationalizes instinctual impressions rather than overriding them. - [12:30](https://www.youtube.com/watch?v=taaEzHI9xyY&t=750s) Software development creates a biological mismatch because human hunter-gatherer brains evolved to evade physical threats and forage for food, not to maintain absolute, defect-free logical consistency across hyper-complex systems. - [10:59](https://www.youtube.com/watch?v=taaEzHI9xyY&t=659s) Commercial programming teams routinely release defective software rather than waiting for unattainable perfection, gambling against edge-case failures because the industry lacks alternatives to human programmers. - [14:44](https://www.youtube.com/watch?v=taaEzHI9xyY&t=884s) JSLint was developed by translating real-world defect patterns submitted to comp.lang.javascript into automated rules, generating defensive reactions from programmers whose emotional habits conflict with empirical data. - [18:42](https://www.youtube.com/watch?v=taaEzHI9xyY&t=1122s) Placing opening curly braces on the right side of a line is mandatory in JavaScript to prevent automatic semicolon insertion from silently converting 'return' followed by a newline into an unintended 'return undefined;'. - [23:44](https://www.youtube.com/watch?v=taaEzHI9xyY&t=1424s) The switch statement's fall-through mechanism, inherited from FORTRAN's computed GOTO via B, creates dangerous ambiguity because human intuition routinely mistakes 'hardly ever happens' for 'never happens.' - [27:29](https://www.youtube.com/watch?v=taaEzHI9xyY&t=1649s) Modern code formatting conventions parallel the historical evolution of written text, where medieval scribes introduced lowercase letters, spacing, and punctuation to halt replication errors when hand-copying manuscripts. - [33:39](https://www.youtube.com/watch?v=taaEzHI9xyY&t=2019s) Immediately invoked function expressions (IIFEs) require defensive wrapping parentheses and explicit semicolons to prevent parsers from erroneously concatenating statements into unexpected function calls. - [36:09](https://www.youtube.com/watch?v=taaEzHI9xyY&t=2169s) The 'with' statement dynamically alters scope at runtime based on object properties, rendering static analysis impossible, blinding code reviewers, and creating severe security hazards. - [37:39](https://www.youtube.com/watch?v=taaEzHI9xyY&t=2259s) Coercive equality ('==') should be abandoned entirely in favor of strict equality ('===') because any language construct that can fail should always be replaced by a safer alternative when the transition cost is zero. - [41:32](https://www.youtube.com/watch?v=taaEzHI9xyY&t=2492s) Because JavaScript historically implemented function scope rather than block scope, declaring variables adjacent to use within loops causes hoisting bugs, necessitating single top-of-function variable declarations. - [45:30](https://www.youtube.com/watch?v=taaEzHI9xyY&t=2730s) Global variables should be styled in obnoxious all-uppercase naming to visibly flag poor design decisions and make architectural compromises explicit to reviewers. - [50:47](https://www.youtube.com/watch?v=taaEzHI9xyY&t=3047s) The '++' increment operator encourages overly complex single-line expressions linked historically to buffer overruns in C-family languages, and should be replaced with explicit '+= 1' syntax to avoid off-by-one errors. - [55:05](https://www.youtube.com/watch?v=taaEzHI9xyY&t=3305s) Curly braces should be strictly mandatory on all control structures, including single-line statements, because omitting them creates visual deception and introduces defects during routine maintenance. - [57:35](https://www.youtube.com/watch?v=taaEzHI9xyY&t=3455s) Language standards committees cannot eliminate broken features due to backwards compatibility, leaving developers responsible for improving software reliability by refusing to write the hazardous subsets of JavaScript. - [01:03:08](https://www.youtube.com/watch?v=taaEzHI9xyY&t=3788s) JavaScript's core elegance stems from combining Scheme's first-class functions and lexical closures with Self's prototypal inheritance, meaning further specification growth dilutes the language rather than improving it.
## Detailed walkthrough ### [00:05](https://www.youtube.com/watch?v=taaEzHI9xyY&t=5s) The Masquerade, Science, and "The Science of Fear"
Douglas Crockford opens his keynote at the Yahoo! Great America campus in Santa Clara, California, joking with the audience by welcoming them to the "YUIConf Gala Costume Masquerade" and praising their festive costumes. He announces the session title: "Section 8, JavaScript Programming Style and Your Brain." Acknowledging that JavaScript, programming style, and human brains might seem like three completely unrelated subjects, Crockford insists there is a genuine, critical, and entertaining connection uniting them.
The foundation of the talk rests on social science research exploring human intelligence and cognitive mechanics. When researchers conducted simple experiments to discover how our brains actually process information, their findings were so counterintuitive that the wider scientific community initially rejected them as flawed experimental design or erroneous data interpretation. However, replication and follow-on experiments repeatedly validated the unexpected results, leading the consensus to shift and eventually resulting in a Nobel Prize. As Crockford explains, this is the classic trajectory of the scientific method: initial consensus is challenged by unexpected findings, verified through independent replication, and recognized.
Crockford points the audience to Daniel Gardner’s book *The Science of Fear*, which chronicles this cognitive research and its societal repercussions. The core insight of Gardner's work is that our mental architecture leaves us fundamentally unequipped to assess danger correctly. As Crockford puts it: “The consequence of fearing the wrong things is that you actually put yourself in greater danger.”
[02:53](https://www.youtube.com/watch?v=taaEzHI9xyY&t=173s) System 1 and System 2: The Gut and the Head
The core discovery centers on two distinct cognitive systems operating within the human brain: System 2 (the "head") and System 1 (the "gut"). The head is the seat of deliberate, analytical thought, complex arithmetic, and deep reflection. Its fatal flaw, however, is speed: it operates quite slowly. Crockford observes that because the head is so slow at number crunching, humanity had to invent computers to handle the calculating demands of the modern world.
In contrast, System 1—the gut—evolved from the fight-or-flight survival mechanism. It acts at lightning speed by looking for broad patterns and reacting instantly, bypassing mathematical precision. Because speed was vital for our ancestors evading predators, the gut’s internal calibration accepts false positives as a necessary tradeoff. Crockford illustrates this with everyday examples, such as a cat suddenly spooking and bolting before casually pretending it intended to do so all along, or an entire flock of birds taking flight simultaneously for no apparent reason.
While people are intuitively familiar with the tug-of-war between their rational thoughts and instinctual impulses, the true scientific revelation lay in how these two modules communicate. The gut does not merely run parallel to the head; it actively feeds assumptions into it. Crucially, the head remains completely unaware that its inputs are being conditioned by the gut, and it systematically values the gut's crude impressions over empirical facts it observed itself.
```mermaid flowchart TD accTitle: Dual-System Brain Architecture accDescr: Flow diagram showing System 1 feeding instinctual premises into System 2, which produces flawed rationalizations.
subgraph S1["System 1: The Gut (Survival)"] G1["Fast Pattern Matching"] G2["Fight or Flight Bias"] G3["Favors False Positives"] end
subgraph S2["System 2: The Head (Analytical)"] H1["Analytical Thought & Math"] H2["Slow & Deliberate"] H3["Rationalizes Starting Premises"] end
G1 -->|"Unconsciously feeds premises"| H1 G2 -.->|"Overrules conscious experience"| H3 ```
- **System 2 (The Head):** Slow, analytical, deliberate, handles arithmetic and abstract reasoning, yet relies on premises handed to it by instinct. - **System 1 (The Gut):** Fast, crude, pattern-matching survival engine calibrated so that false positives are preferred over dangerously slow reactions. - **The Cognitive Glitch:** “The things that the gut tells the head are weighed as more important than things that the head itself has experienced.”
[05:17](https://www.youtube.com/watch?v=taaEzHI9xyY&t=317s) How Advertising Hacks the Gut: The Tobacco Paradox
While the dynamic between the gut and the head was a revelation to academic science, Crockford notes that the advertising industry had already mastered it decades earlier. Marketers sustain their businesses by engineering synthetic desires—getting consumers to buy things they do not need. They achieve this by bypassing the analytical head and targeting the gut directly, a tactic perfected by the tobacco industry.
On a purely rational level, tobacco offers an absurd value proposition: lighting up immediately causes foul breath, yellows teeth, brings on disease, and ends in a premature death. Attempting to sell cigarettes logically to the head would fail completely. Instead, advertisements target the gut. Because human instincts evolved to scan for immediate, dramatic threats, the gut is blind to slow, distant hazards. Crockford notes with dark humor: “Slow death doesn't register. So slow death is as good as good for you.”
When a smoker is asked analytically why they continue smoking, their head generates rationalizations based on premises already warped by the gut. Crockford sketches the scene of a smoker in a restaurant convinced that smoking makes them popular, entirely oblivious to nearby patrons recoiling from the smell to protect their food. Furthermore, while chemical dependence plays a part, it cannot account for fierce brand loyalty, where people steadfastly purchase the single brand that hooked them until it kills them. That lifelong dedication is not simple chemical addiction; it is gut-level manipulation.
[08:12](https://www.youtube.com/watch?v=taaEzHI9xyY&t=492s) The Complexity of Software and the Mirage of AI
Pivoting away from human cognitive quirks, Crockford examines computer programs, which he characterizes as the most complex artifacts human beings create. Although physical machines like airplanes are extraordinarily complex, their single most intricate and failure-prone component is always the software running them. Programs consist of immense webs of statements, variables, and functions that must coordinate seamlessly under staggering levels of complexity.
Early on in computing history, practitioners recognized that human beings were poorly suited for this kind of work. The prevailing dream was that developers could construct artificial intelligence programs capable of generating better software than humans could, iteratively bootstrapping until computers took over entirely. Crockford deadpans: “Once we can get the program to do that, we can then tell the programs 'make a program that's better than you,' and we keep doing that until they become our overlords. That didn't happen.” AI conquered Grandmaster chess and could play *Jeopardy!*, but it cannot parse requirements and custom router views to generate working applications. Programming remains an intensely manual craft.
Because humans are still writing code by hand, programming languages serve as our most powerful abstraction tools, acting as a direct partnership between human thought and the machine. However, languages also impose cognitive boundaries. If a language lacks closures or recursion, developers remain completely blind to the power and utility of those paradigms. Programming languages actively govern how developers think, working both for them and against them.
[10:59](https://www.youtube.com/watch?v=taaEzHI9xyY&t=659s) The Burden of Perfection and the Hunter-Gatherer Mind
The central hardship of programming is its zero-tolerance demand for absolute perfection across every edge case, input, and unanticipated circumstance. When an unhandled flaw occurs, the hardware takes full license to execute the worst possible behavior at the most catastrophic time. In human-machine collaboration, blame is never assigned to the silicon. As Crockford emphasizes: “It is the programmer's fault for having created a program that was not perfect.”
Under ideal engineering standards, developers would withhold software, continuously refining and debugging until it achieved genuine perfection before release. In commercial practice, doing so would guarantee that nothing ever ships. Instead, software teams release products known to be defective and gamble that catastrophic bugs will not emerge before the next update cycle.
This demand creates a structural mismatch with human biology. Humans are profoundly imperfect creatures who have undergone no meaningful evolutionary adaptation since the Paleolithic era. Beneath the veneer of modern technology, programmers remain primitive hunters and gatherers attempting to build flawless, hyper-complex systems using brains designed for survival on the savanna. Crockford concedes: “I am a very imperfect person, but I program because we've got no one else to do it.”
[12:30](https://www.youtube.com/watch?v=taaEzHI9xyY&t=750s) The Evolutionary Mismatch: Programming With a Hunter-Gatherer Brain
Modern software engineers are operating with the exact same brains as prehistoric humans. Evolution selected human faculties for very practical survival tasks: the brain evolved strategies for hunting and gathering food, while the gut evolved fight-or-flight instincts to escape predators. Today, developers take that exact cognitive architecture and attempt to program computers with it—an activity for which it was never intended. Douglas Crockford marvels that this works at all, calling the fact that humans can program miraculous and crazy. Analytical reasoning handles the state of the program and builds the mental model required to reason about code, yet teaching someone how to program remains notoriously difficult because there is no standardized algorithm for human problem-solving.
When decomposing an engineering problem, developers switch directions constantly: jumping from top-down to bottom-up, or working inside-out and outside-in. Nobody can clearly describe how this mental maneuvering happens, yet programmers perform it daily. Crockford suggests it is the gut—the subconscious intuition—that prompts developers to jump between strategies and provides the occasional flashes of insight that make a program come together. However, that reliance on intuition comes with a serious liability. The essence of software craft lies in balancing tradeoffs, such as trading space for speed, because absolute perfection is unattainable. The gut is notoriously awful at evaluating tradeoffs, and instead of assisting the engineer, it often creates severe cognitive hindrances.
> “We're using that brain now to program computers, and there is no reason to think that that should work.” — Douglas Crockford
> “We could not program without our gut.” — Douglas Crockford
> “I have absolutely no evidence to justify that statement. But my gut tells me it's true, so I believe it.” — Douglas Crockford
- Human faculties evolved for finding food (analytical brain) and fleeing danger (gut instinct). - Teaching programming is difficult because no explicit algorithm exists for how engineers decompose problems across varying strategies. - The craft of programming requires constant tradeoffs, but human gut instinct is uniquely bad at weighing those tradeoffs objectively.
---
[14:44](https://www.youtube.com/watch?v=taaEzHI9xyY&t=884s) The Genesis of JSLint and the Usenet Crucible
While the cognitive principles Crockford explores apply to all programming languages, JavaScript serves as the primary case study because of its extreme contrast between elegance and dysfunction. Brendan Eich designed JavaScript in roughly ten days. While Eich managed to incorporate profound ideas—what Crockford jokingly calls discovering the "good parts," the first important discovery of the 21st century—the tight timeframe meant bad features were rushed in without adequate vetting. Crockford admits his first couple of years with JavaScript were excruciating, largely because he committed the classic blunder of writing code in the language before actually bothering to learn it.
To survive the language's numerous sharp edges, Crockford decided to construct a static analysis tool. He began with a Pratt parser, an efficient top-down operator precedence technique that allows a developer to stand up a compiler with minimal overhead. Once he had a working JavaScript parser written in JavaScript, he turned it into a linter. To source real-world test cases, Crockford hung out on the Usenet newsgroup `comp.lang.javascript`, where programmers routinely posted broken snippets asking for help. Whenever a snippet revealed a recurring bug pattern, Crockford coded an automated detection rule into JSLint. When snippets were too convoluted to analyze deterministically, it revealed the necessity of a coding discipline—a consistent stylistic constraint that makes code verifiable as correct or incorrect.
```mermaid flowchart TD accTitle: Origin and Growth of JSLint accDescr: Process showing how Douglas Crockford used a Pratt parser and Usenet bug reports to build JSLint rules and coding disciplines.
subgraph Engine ["Tool Construction"] A["Pratt Parser Technique"] --> B["JavaScript Compiler in JS"] B --> C["JSLint Prototype"] end
subgraph Feedback ["Usenet Crucible (comp.lang.javascript)"] D["User submits broken code snippet"] D --> E{"Can flaw be determined automatically?"} E -->|"Yes: Pattern identified"| F["Add automated lint rule"] E -->|"No: Code too convoluted"| G["Formulate coding discipline"] F --> C G --> C end ```
> “JavaScript was designed in about ten days, and somehow in those ten days Brendan Eich managed to get some good parts in it -- and they are really, really good -- but he got a lot of bad stuff.” — Douglas Crockford
> “My first couple of years working with JavaScript were extremely painful, partly because I decided not to learn the language before I started working in it, which was about as stupid a thing as you could do.” — Douglas Crockford
---
[17:36](https://www.youtube.com/watch?v=taaEzHI9xyY&t=1056s) Hurt Feelings and the Rationalized Gut
JSLint quickly developed a reputation that led to Crockford's famous disclaimer: "JSLint will hurt your feelings." Crockford notes the deluge of emails he receives from developers whining about the linter flagging their code. The psychological contradiction is striking: engineers intentionally run JSLint, an automated quality tool created specifically to highlight flaws and push them toward cleaner code, yet react with deep personal offense when it does exactly that.
Crockford attributes this friction to cognitive interference caused by the gut. The rules inside JSLint were not chosen on arbitrary whims; they were derived empirically by inspecting real programs that failed in production and identifying the root syntax habits that caused those failures. Because average developers have not analyzed thousands of broken Usenet programs to witness how easily certain constructs fail, their gut instinct rebels against JSLint's strict constraints, mistaking familiar habits for good practices.
> “JSLint comes with a warning: JSLint will hurt your feelings.” — Douglas Crockford
> “Why are they complaining that it's telling them how to make their programs better?” — Douglas Crockford
---
[18:42](https://www.youtube.com/watch?v=taaEzHI9xyY&t=1122s) The Brace Wars: Arbitrary Conventions vs. JavaScript Semicolon Insertion
The irrationality of developer intuition is nowhere clearer than in the decades-old debate over curly brace placement. When Ken Thompson created the B language, he placed opening braces on the right side of the statement line. Dennis Ritchie copied that syntax for C. Yet colleagues in their Bell Labs environment vehemently insisted braces belonged on the left because they felt it looked better aesthetically. Crockford points out that outside of specific language quirks, the decision is entirely arbitrary—analogous to driving on the left in the United Kingdom versus driving on the right in the United States. Neither is intrinsically correct; what matters is total societal consensus, because switching sides at random causes chaos. (Crockford notes that when he shared this driving analogy during a presentation in Bangalore, the audience was entirely perplexed by the comparison.)
Yet when a developer who prefers braces on the left joins a shop mandating braces on the right, emotional turmoil ensues. Programmers will nearly burst into tears, insisting that right-hand braces are fundamentally wrong and struggling to invent logical justifications, such as claiming the left side is inherently "more readable." Engineers fancy themselves analytical mathematicians, yet they experience visceral grief over moving a punctuation mark between lines. Thompson could have ended the argument decades ago by having the B compiler reject left-aligned opening braces with a hard syntax error, but by leaving the grammar loose, he introduced room for arbitrary personal preference.
In JavaScript, however, brace placement ceases to be an arbitrary aesthetic debate: there is an absolute, objectively correct answer. Because of JavaScript's automatic semicolon insertion (ASI), placing an opening brace on the left beneath a `return` statement triggers a silent disaster. Instead of returning the intended object literal, the runtime automatically inserts a semicolon after `return` and returns `undefined`. No compile-time error is raised, no runtime exception is thrown, and the application fails silently minutes later in an unrelated execution path. Debugging this can cost hours of staring at syntactically valid code. Placing braces consistently on the right eliminates this failure class entirely at zero net cost, making it the only rational tradeoff—yet developers will still resist, with one attendee even telling Crockford they would put braces on the right *only* for `return` statements while stubbornly keeping them on the left everywhere else.
```mermaid flowchart LR accTitle: JavaScript Automatic Semicolon Insertion Hazard accDescr: Diagram illustrating how split-line return statements silently return undefined due to ASI versus same-line braces.
subgraph Unsafe ["Left-Aligned Brace (Error-Prone)"] R1["return"] -->|"ASI adds ';'"| Undef["Returns undefined!"] Brace1["{ key: value }"] -->|"Evaluated as dead code"| Dead["Ignored block"] end
subgraph Safe ["Right-Aligned Brace (Error-Resistant)"] R2["return {"] -->|"Parser sees open literal"| Obj["Returns Object literal"] Brace2[" key: value\n};"] --> Obj end ```
> “We're programming computers, we're analytical, we're mathematicians, we're laying this stuff out, and we're crying because we had to move a piece of punctuation from one line to another.” — Douglas Crockford
> “He could have easily fixed his B compiler and said it's got to be on the right, dammit, and shut up or you get a syntax error, end of story.” — Douglas Crockford
> “Prefer forms that are error resistance. For no cost, if you just say I'll do this thing for which there isn't a right answer and do it this way, you avoid a terrible problem, and the net cost of doing that is zero.” — Douglas Crockford
- Ken Thompson (B) and Dennis Ritchie (C) placed opening curly braces on the right side of the line. - Consistency across a team is paramount; mixing brace styles inside the same codebase is universally recognized as sloppy. - JavaScript's automatic semicolon insertion turns a split-line `return` and object literal into an unprompted `return undefined;`. - The rule of code style: Adopt error-resistant conventions whenever the cost of adopting them is zero.
---
[23:44](https://www.youtube.com/watch?v=taaEzHI9xyY&t=1424s) The Switch Statement: FORTRAN’s Computed GOTO Legacy
Crockford transitions to the design history of the `switch` statement, another construct influenced by Ken Thompson. When designing the statement for B, Thompson modeled it directly after FORTRAN's computed `GOTO` statement—a control structure that was already falling out of favor among computer scientists but had not yet been universally recognized as harmful.
Because of this architectural heritage, a `switch` block does not represent a clean collection of isolated discrete cases. Instead, it is essentially a series of jump labels where control flow falls through from one case label into the next unless an explicit `break` interrupts it. This fall-through behavior introduces severe visual and practical ambiguity: when reading source code, it is remarkably difficult to determine whether a programmer omitted a `break` deliberately or accidentally. Early in JSLint’s lifecycle, a user reached out to Crockford pointing out how frequent and difficult-to-debug fall-through defects were, requesting that the linter flag fall-throughs by default to enforce clear structural boundaries.
> “The switch statement was designed by Thompson. He modeled it after the Fortran computed goto statement, which is now recognized as harmful.” — Douglas Crockford
> “There's this goto-ness in it, in which you really don't have a set of cases, you've got a set of labels and the code will fall through to each other.” — Douglas Crockford
- The `switch` statement inherits its mechanics from FORTRAN's computed `GOTO`, treating `case` statements as jump labels rather than scoped blocks. - Unintentional fall-through is historically one of the most stubborn and invisible bugs in C-family languages. - Early community feedback on `comp.lang.javascript` prompted JSLint to explicitly monitor and warn against unannotated case fall-throughs.
[24:36](https://www.youtube.com/watch?v=taaEzHI9xyY&t=1476s) Achieving Enlightenment: The Fall-Through Fallacy and the Flawed Gut
Douglas Crockford recounts a humbling interaction with a developer who questioned whether JSLint should flag switch statement case fall-throughs. Crockford had initially reasoned that while accidental fall-throughs do happen, they are exceedingly rare, whereas intentional fall-through allows for clever, elegant control flow optimization. Looking at that tradeoff, he decided JSLint should not issue a warning. The very next day, however, that same developer submitted a bug report for JSLint itself. Crockford fired up the debugger to investigate, only to discover that the root cause was an accidental fall-through case inside his own code. “In that moment, I achieved enlightenment,” Crockford admits.
He uses this episode to dissect human cognition and how software developers delude themselves. Programmers like to imagine that the bulk of their working hours is spent in bursts of hyper-productive "power typing," churning out functional code. In reality, Crockford points out, programmers spend most of their time staring blankly into the abyss, asking themselves what they have done and how they will ever make the code work. Once a solution is found, the brain conveniently erases all memory of the struggle—much like how the human gut erases false-positive fight-or-flight reactions so the body can react swiftly rather than analyze past errors.
The core mistake was trusting gut instinct over basic mathematical logic. When Crockford told the developer that fall-through bugs "hardly ever happen," he fell into an intuitive cognitive trap: “That hardly ever happens means the same thing as it happens.” The subconscious gut does not understand numbers properly; it treats "a lot" as having greater weight than "all," and equates "not very often" with "never." Trusting that faulty arithmetic led him straight to an erroneous design decision about the safety of switch statements.
- Mathematical logic vs. gut estimation: the gut treats infrequent occurrences as effectively zero ("never"), leading to dangerous assumptions in program safety. - Memory bias: developers systematically forget the hours spent debugging and agonizing over bugs once they finally resolve them.
[26:36](https://www.youtube.com/watch?v=taaEzHI9xyY&t=1596s) Looking into the Abyss: Why Programmers Are Abnormal
When developers make errors, they routinely brush them off and keep going. This chronic tolerance for failure leads Crockford to argue that there is fundamentally something abnormal about software engineers. Early in his career, when he first learned how to map the world into data structures and algorithms, he evangelized coding, believing it was such a magnificent conceptual framework for organizing information that every person on earth should learn it. Over time, he completely abandoned that perspective.
He now believes that normal people simply do not have the tolerance required for software development. Faced with the inevitable wall of broken logic and endless troubleshooting, a reasonable human being walks away. As Crockford explains: “A normal person, once they've looked into the abyss, would say I'm done, this is stupid, I'm going to go do something else.” Programmers, by contrast, persist in staring down the abyss precisely because "there's something really wrong with us."
[27:29](https://www.youtube.com/watch?v=taaEzHI9xyY&t=1649s) The Evolution of Written Style: From Rome to the Printing Press
Turning to programming style, Crockford rejects the notion that formatting should be treated as a medium for artistic vanity, personal taste, or individual self-expression. Many developers assume that because a compiler or interpreter discards whitespace and comments, that ignored space is an open playground to show off or amuse oneself. To explain why code style matters, Crockford traces the historical evolution of written text. The ancient Romans wrote Classical Latin in *scriptio continua*—exclusively in uppercase letters, without spaces between words or punctuation. While Rome managed to conquer the Western world using this format, reading it required immense cognitive parsing effort, where a phrase like "NOW OR DB REAKS" could easily be misread.
```mermaid flowchart TD accTitle: Evolution of Text Conventions accDescr: Progression from Roman scriptio continua to modern standardized text through error-reduction innovations. subgraph Antiquity ["Antiquity"] A["Roman Scriptio Continua<br>(All uppercase, no spaces, no punctuation)"] B["Mass hand-copying of Christian scriptures<br>(Copies of copies diverge wildly)"] A --> B end
subgraph MiddleAges ["Middle Ages"] C["Medieval Copyists Innovate<br>(Add lowercase, spaces, punctuation)"] D["Dramatically Lower Error Rates<br>(Rapid parsing, accurate replication)"] B --> C C --> D end
subgraph PrintAndWeb ["Print & Modern Computing"] E["Gutenberg Bible Adopts Conventions"] F["Universal Standard for Print, Web, & Code"] D --> E E --> F end ```
This dense writing system functioned adequately until Emperor Constantine made Christianity the state religion of the Roman Empire, creating an urgent institutional demand to duplicate and distribute sacred scriptures across the territory. Scribes faced a catastrophe: lacking original manuscripts, they worked from copies of copies of copies, none of which agreed. Because church authority rested upon the absolute truth of the written word, conflicting transcriptions posed an existential crisis. Hand-copying uninterrupted blocks of Roman capital letters proved hopelessly error-prone.
To solve this replication crisis, medieval copyists introduced lowercase letterforms, word boundaries, and standardized punctuation. These innovations drastically reduced cognitive overhead, allowing scribes to extract information quickly and copy text faithfully. Johannes Gutenberg later adopted these identical conventions when typesetting his Bible, establishing a standard that persisted through print into modern internet typography:
> “It worked -- this was a very effective way of making their copying much more reliable.”
Crockford argues that programming code demands the exact same rigor. A program's primary objective is to be understood by human beings, and centuries of typography prove that structured style directly mitigates errors. Drawing a parallel to literary style guides, he references William Strunk Jr.’s classic *The Elements of Style*, noting that while some century-old English usage recommendations have aged, the fundamental principle—clear, concise composition aimed at human comprehension—remains timeless.
[31:04](https://www.youtube.com/watch?v=taaEzHI9xyY&t=1864s) Readability, Composition, and Disambiguating Parentheses
Because modern software development has shifted toward continuous, agile processes, a codebase is never truly finished or permanently "in the can." Consequently, code must always remain editable, which requires it to be effortlessly readable. The compiler's ability to understand source code is actually the lowest bar of success; the true priority is human communication. Basic compositional rules from natural language should carry over wherever appropriate: for instance, placing a space after a comma rather than before it. While a compiler will gladly accept a space preceding a comma, doing so produces sloppy, disjointed code that looks ridiculous.
Natural language grammar, however, falls short of the extreme precision software demands. Early experiments in designing programming languages that mimic English failed because natural prose is riddled with ambiguity, and computers lack the intelligence to parse stylistic eccentricities. Code introduces novel syntactical collisions that require deliberate whitespace conventions. A prime example is the dual role of parentheses in JavaScript, which represent either mathematical grouping or function invocation:
- **Invocation:** When calling a function `foo()`, no space should sit between the identifier and the opening parenthesis, signaling that the arguments belong directly to the callable target. - **Grouping:** When grouping an expression or statement—such as after a `return` keyword—a space must separate the keyword and the opening parenthesis (`return (x);`). While `return` can be a function call in certain other languages, it is a statement keyword in JavaScript. - **Anonymous Functions:** Writing `function()` looks visually like calling a function named "function." Inserting a space (`function ()`) clarifies that it is an anonymous function literal rather than an invocation.
Crockford acknowledges that an experienced engineer can eventually figure out bad syntax, but argues that deciphering erratic formatting squanders cognitive reserves: “They shouldn't be trying to get past your syntax and your lousy grammar, they should be trying to understand the thoughts and the structures of the program so they can make it work.”
[33:39](https://www.youtube.com/watch?v=taaEzHI9xyY&t=2019s) Immediately Invoked Functions and Automatic Semicolon Insertion Hazards
Crockford evaluates Immediately Invoked Function Expressions (IIFEs), noting that while they are an exceptionally useful design pattern in JavaScript, they harbor syntactical traps. A function literal cannot legally begin a statement because the JavaScript parser automatically interprets a leading `function` keyword as a function declaration—which cannot be immediately invoked. To force the parser into expression mode, developers wrap the structure in parentheses.
Crockford objects to the common convention of wrapping only the inner function and leaving the invoking parentheses dangling on the outside (`(function () {... })()`). Visualizing the invocation as a singular, cohesive operation, he jokes that the trailing parentheses look awkward hanging off the edge:
> “What we're talking about is the whole invocation but we've got these things hanging outside of it looking sort of like dog balls.”
Instead, Crockford advocates wrapping the entire invocation inside the grouping parentheses: `(function () {... }());`. This visually and syntactically unites the entire execution unit between the outer parens.
``` // Crockford's preferred, unified IIFE form: (function () { //... }());
// The awkward "dog balls" trailing-invocation form: (function () { //... })(); ```
He pairs this with a stern warning regarding Automatic Semicolon Insertion (ASI). If a programmer omits a semicolon on the line preceding an immediately invoked function, the runtime parser will combine the two lines. Instead of assigning `x = y;` and then executing the anonymous closure as an independent statement, the JavaScript engine interprets `y` as a function identifier and passes the anonymous function literal directly into `y` as an argument (`x = y(function () {... }())`). This causes silent, catastrophic failures that can consume hours of manual code inspection. Crockford warns: “The moral of this is: do not rely on automatic semicolon insertion. Put all of the semicolon insertions in all of the places where they're supposed to go and nowhere else, because if you don't, things like this happen to you.”
[36:09](https://www.youtube.com/watch?v=taaEzHI9xyY&t=2169s) The Unpredictable Hazard of the `with` Statement
Crockford moves to another feature of the language: the `with` statement. Although originally conceived with good intentions to shorten repetitive property chains, the statement is fundamentally broken. By dynamically modifying the scope chain at runtime based on the object passed to it, the `with` statement creates complete lexical ambiguity.
Presenting a slide containing a green `with` block, Crockford challenges the audience to identify which variable or property it actually mutates. Because property lookups depend entirely on the dynamic runtime contents of the target object, reading the code provides no certainty about what will happen. In fact, every single time the statement executes, it can bind to entirely different targets. This makes static analysis impossible and renders human code reviews useless, cementing the feature's status as a dangerous anti-pattern that JSLint systematically rejects.
[36:43](https://www.youtube.com/watch?v=taaEzHI9xyY&t=2203s) Eliminating the `with` Statement and Banishing Confusion
Douglas Crockford urges developers to eradicate the `with` statement from their JavaScript codebases entirely. While defenders often argue that `with` can be used cleverly for specific, highly useful tasks, Crockford counters that utility is not the standard: the construct is fundamentally and inherently confusing. In software engineering, confusion is the root driver of defects, vulnerabilities, and misery, meaning clean code requires absolute clarity rather than dangerous cleverness.
As Crockford puts it: “Confusion is what causes bugs and security mishaps and all the other things that make us miserable.” Because there is nothing achievable with a `with` statement that cannot be accomplished just as effectively without one, eliminating it incurs zero penalty while immediately removing an entire surface area for developer error.
[37:39](https://www.youtube.com/watch?v=taaEzHI9xyY&t=2259s) The Flaws of Double Equal (`==`) and the Zero-Cost Rule
JavaScript’s coercive equality operator (`==`) was recognized as broken from the very beginning. Brendan Eich knew it was defective and attempted to repair it during the language’s standardization committee meetings; however, Microsoft adamantly insisted on keeping the broken behavior in the ECMAScript specification. Eich was fortunately able to slip the strict equality operator (`===`) into the language late in the process. Crockford advises never using `==` under any circumstances, even in rare edge cases where type coercion happens to produce the desired result.
When a reviewer encounters `==` in code, they are forced to stop and wonder whether the author discovered an obscure edge case where coercion works, or if the author is simply incompetent. Writing code that is indistinguishable from a common mistake wastes reader attention and undermines trust. Crockford highlights a universal rule of language trade-offs: “If there's a feature of the language that is sometimes problematic and if it could be replaced by another feature that is more reliable, then always use the more reliable function.” Replacing `==` with `===` costs nothing and completely eliminates a category of bugs.
[39:09](https://www.youtube.com/watch?v=taaEzHI9xyY&t=2349s) The Pitfalls of Multiline String Literals
ECMAScript 5 introduced multiline string literals using escaped newlines, a feature Crockford strongly dislikes for both aesthetic and structural reasons. First, escaping newlines breaks standard indentation in deeply nested code by forcing continuation text all the way back to the left margin, ruining readability. Second, the syntax introduces severe fragility: an invisible space accidentally typed immediately after the backslash causes a syntax error.
``` // Looks correct: var str = "line one \ line two";
// Has an invisible syntax error (trailing whitespace after backslash): var str = "line one \ line two"; ```
Because an error caused by an invisible trailing space is nearly impossible to spot by sight, Crockford rejects the entire construct. Code should be manifestly and obviously correct rather than relying on brittle visual ambiguities. When programmers protest that they use misleading syntax intentionally, Crockford dismisses the argument: “If you knew what you were doing, you wouldn't be doing that.”
[40:48](https://www.youtube.com/watch?v=taaEzHI9xyY&t=2448s) Ambiguous Syntax in C-Style Languages
In C-family languages, statements where assignment and equality can easily be transposed cause pervasive comprehension bugs. A statement intended to perform one action can closely mimic a completely different operation, leaving the reader unable to determine intent.
When a snippet of code can be interpreted as either an accidental syntax mistake or a bizarrely valid edge case, the reviewer cannot tell what was intended. Crockford remarks: “All we know for sure is that the programmer's incompetent.” The remedy is simple: write explicit, unambiguous expressions using parentheses or separate assignments so the author's true objective is obvious at a glance.
[41:32](https://www.youtube.com/watch?v=taaEzHI9xyY&t=2492s) Function Scope, Hoisting, and Top-of-Function Declarations
Scope—the boundary ensuring declared variables are invisible outside their enclosing block—was introduced in ALGOL 60 and remains one of the greatest inventions in programming language history. Most modern languages provide block scope, but JavaScript historically only provided function scope: any variable declared anywhere inside a function is visible throughout that entire function. The problem is that JavaScript's block syntax (`{... }`) mimics block-scoped languages like C and Java, misleading engineers about variable lifetime and visibility.
```mermaid flowchart TD accTitle: JavaScript Var Hoisting Mechanism accDescr: Diagram illustrating how a var statement inside a block is split into a hoisted declaration at function top and an assignment left in place.
subgraph SourceCode ["Author's Written Code"] S1["function foo()"] S2["{... if (cond) { var x = 10; }... }"] end
subgraph RuntimeEngine ["Engine Parsing & Hoisting"] H1["Declaration hoisted to function top: var x = undefined;"] H2["Assignment remains in place: x = 10;"] end
SourceCode --> RuntimeEngine ```
In block-scoped languages, declaring a variable immediately adjacent to its first use is best practice. In JavaScript, following that advice produces severe confusion due to hoisting: the declaration (`var`) is automatically extracted and hoisted to the top of the function initialized to `undefined`, while the assignment remains in place. Crockford stresses that developers should never pretend the language works differently than it does: “Because of that confusion, I recommend declaring all of your variables at the top of the function.” He adds that all functions should likewise be declared before they are invoked, making code reflect its true runtime behavior.
[44:22](https://www.youtube.com/watch?v=taaEzHI9xyY&t=2662s) The Fallacy of `for (var ...)` Loops
One of the hardest habits for developers to break is declaring loop induction variables inside the loop header (`for (var i = 0;...)`), a pattern ingrained from Java. In Java, `i` is cleanly scoped to the `for` loop body. In JavaScript, however, that variable is scoped to the entire enclosing function.
If closures or asynchronous callbacks inside the loop body depend on loop-level variable scoping, the program breaks, producing subtle defects that trap even seasoned engineers. Programmers must accept the reality of the environment they are using rather than transplanting habits from other ecosystems. Crockford emphasizes: “This is a different language; it has different rules, different conventions, different good parts, and you need to respect that.”
[45:30](https://www.youtube.com/watch?v=taaEzHI9xyY&t=2730s) Global Variables and the All-Uppercase Naming Convention
Crockford identifies global variables as JavaScript's greatest flaw. They degrade program reliability and undermine security, yet the browser environment is deeply entangled with them. While ECMAScript design work—such as upcoming proposals from Dave Herman—aims to address these deficiencies, developers must currently minimize globals, ideally reducing them to a single namespace or eliminating them entirely.
When global variables are unavoidable, Crockford advocates writing them in all-uppercase letters:
- **Visibility:** Globals should be as rare as hen's teeth and stick out like a sore thumb. - **Obnoxiousness:** Uppercase is visually aggressive and jarring, emphasizing that creating a global is an undesirable workaround. - **Overcoming C/Java Misconceptions:** In C, all-uppercase was created at Bell Labs to distinguish dangerous preprocessor macros from variables. Java copied uppercase naming for `final` constants even though language-level constants did not require macro protection. JavaScript developers often resist uppercase globals because they expect it to mean "constant," even though JavaScript historically lacked `final`. Crockford insists the convention should be reclaimed for something that actually matters in JavaScript: flagging hazardous global state.
As Crockford explains: “All uppercase seems to be the most obnoxious way you can write a variable name, so that's the way I want to write it so it's really clear that this is stupid.”
[47:42](https://www.youtube.com/watch?v=taaEzHI9xyY&t=2862s) The Perils of the `new` Prefix and Forgotten Constructors
Crockford notes that he has entirely abandoned the `new` prefix in his own programming, preferring `Object.create` exclusively. The fatal flaw with JavaScript's constructor mechanism is syntactic: if an author writes a constructor function designed for `new` and a caller accidentally invokes it without the `new` operator, the `this` binding falls back to the global object.
Instead of instantiating and configuring a fresh object, the function silently overwrites and clobbers global variables. Crockford quips: “It's the worst -- maybe second worst -- thing it could do. Maybe it could kill somebody; that might be worse.” While ECMAScript 5 strict mode resolves this defect by preventing `this` from defaulting to the global object, developers in 2011 could not rely on that fix in production environments because strict mode was missing entirely from Internet Explorer 6, 7, 8, and 9.
[48:41](https://www.youtube.com/watch?v=taaEzHI9xyY&t=2921s) InitialCaps Conventions and Variable Declarations
Douglas Crockford observes that while ECMAScript 5 strict mode will eventually provide substantial value, developers currently depend on naming conventions to maintain code clarity. Specifically, JavaScript relies on the InitialCaps convention: any function starting with an initial capital letter must be reserved strictly for constructors invoked with the `new` operator. Without this convention, reading a program to verify whether constructors and the `new` keyword are used correctly is virtually impossible. Crockford emphasizes that some ecosystems fail to grasp this necessity, adding, “Microsoft still hasn't figured this out.”
```mermaid flowchart TD accTitle: Constructor Naming Rule accDescr: Visual flowchart outlining the naming convention rule for JavaScript functions and constructor invocation.
A["Function Identifier"] --> B{"Starts with InitialCap?"} B -- Yes --> C["Must be invoked with 'new'"] B -- No --> D["Must NOT be invoked with 'new'"] ```
Moving on to variable declarations, Crockford illustrates how sloppy syntax obscures developer intent. He displays an example where a `var` statement appears to mean one thing on paper, but under JavaScript's actual hoisting semantics means something completely different. When examining code written like that, Crockford quips, “Again, you have to look at it and ask what the intention was here, and again, all you really sure know for sure is the programmer was incompetent.” He stresses that developers must write code that unambiguously expresses their true purpose rather than leaving reviewers to guess. Looking forward, Crockford welcomes the eventual introduction of the `let` statement to JavaScript, which respects block scope rather than function scope and eliminates hoisting pitfalls. Once block scoping becomes widespread across browsers, his standing rule will reverse: instead of telling developers to hoist all declarations to the top, he will advise them to abandon `var` completely. However, that transition remains distant because developers must still support legacy versions of Internet Explorer:
- IE6 - IE7 - IE8 - IE9 - IE10
---
[50:47](https://www.youtube.com/watch?v=taaEzHI9xyY&t=3047s) The Hazards of the `++` Operator
The `++` operator originated in C, designed specifically for pointer arithmetic so programmers could advance a pointer to the next memory location. Crockford asserts that pointer arithmetic has long since proven to be a dangerous concept, noting that “The last popular language with point arithmetic was C++, a language so bad it was named after this operator.” Despite the complete absence of pointers in JavaScript, the operator remains, serving merely to add one to a variable while creating side effects that inevitably produce confusion.
Beyond its mechanics, Crockford points out the psychological trap of `++`. The operator triggers an irresistible compulsion in developers to pack as much logic into a single line as possible:
> “Most of the buffer overrun craze in the eighties and nineties, where it was so easy to take over operating systems, was because of this operator; it just is so easy for the enemy to get something into memory and get it executed because this encourages you to write stuff which is just way too damn clever, way too difficult to understand.”
Crockford admits that he does not trust himself to use the operator even in standard `for` loop headers, because using it triggers a "twitch" that makes him try to cram expressions together with comma operators onto a single line. Consolidating code onto one line provides zero benefit and extracts a steep price in readability and reliability. For that reason, he bans the operator from his own code and exclusively writes `+= 1`.
When developers push back and argue that `x++` is one character shorter and means the same thing, Crockford points out that saving a keystroke has no value, and moreover, the statement is factually wrong: post-increment (`x++`) does not behave the same as `+= 1` or pre-increment (`++x`). Intermixing post-increment and pre-increment creates subtle, transient off-by-one errors that are notoriously painful to debug. When reviewing code that carelessly mixes the two forms, a reviewer is forced to evaluate every single occurrence to determine whether the author understood the evaluation order. As an example of careless code, Crockford recalls seeing adjacent statements written as `++x; ++x;`. If the original code had been written as `x += 1;`, the author could have updated it cleanly to `x += 2;`, but instead doubled the line—or perhaps introduced a copy-paste error. He concludes: “So for no cost, by adopting a more rigorous style, many classes of errors can be automatically avoided.”
---
[55:05](https://www.youtube.com/watch?v=taaEzHI9xyY&t=3305s) Required Braces and Defensive Programming
Turning to control structures, Crockford targets optional curly braces as one of the most enduring design blunders in language history. Ken Thompson made curly braces optional on structured statements when designing B, Dennis Ritchie carried that mistake into C, and nearly every subsequent language copied it. In Crockford's view, designers should have made the parentheses optional instead of the braces. Omitting braces produces misleading visual structures where indented statements look conditional but execute unconditionally.
```mermaid flowchart LR accTitle: Language Lineage of Optional Braces accDescr: Sequence diagram showing how the optional curly brace design mistake propagated from B into modern languages.
B_Lang["B (Ken Thompson)"] --> C_Lang["C (Dennis Ritchie)"] C_Lang --> Modern["Most Modern Languages (JavaScript, etc.)"] ```
Crockford's rule is absolute: always include curly braces around blocks, even for single-line statements:
- It costs only two additional characters. - It prevents maintenance programmers from breaking logic when adding subsequent statements. - It builds resilient code suited for modern agile environments where files are modified constantly.
He dismisses complaints about the extra keystrokes, arguing that developers do not spend the majority of their time typing. Omitting braces under the illusion of typing speed results in wasting hours chasing structural defects. Crockford states: “Computer programs must be perfect and humans are not perfect, so that is the struggle; that is the core problem in our craft.”
Style rules must be chosen not for visual appeal or familiarity, but for their ability to lower human error rates. If developers want to be more productive, they need to spend less time "staring into the abyss" trying to decipher arcane bugs.
---
[57:35](https://www.youtube.com/watch?v=taaEzHI9xyY&t=3455s) Subsetting JavaScript and the Philosophy of JSLint
Crockford explains that the JSLint style rules originated from a practical effort to automate error detection. Along the way, he adopted a governing design principle: “I decided that forms that can hide defects are themselves considered to be defects.” He clarifies that these opinions were not preconceived biases, but lessons learned the hard way over years of working with a deeply flawed language:
> “JSLint taught me JavaScript. I know what I know about JavaScript because JSLint taught me. JSLint is much smarter about JavaScript than I am. It's probably smarter than you are, too.”
His approach to mastering JavaScript relies on aggressive subsetting. Any language feature that introduces ambiguity or risk and can be lived without should simply be discarded. While language designers and standards bodies can never remove broken or dangerous features from a widely used language without breaking existing programs, ordinary developers have an immense power: they can eliminate any feature simply by refusing to write it. Developers should know the entire language thoroughly, but use that knowledge specifically to avoid features that work against them. Subsetting does not guarantee zero bugs, but it shifts the odds into the programmer's favor. Crockford concludes his talk with the takeaway: “Good style is good for your gut, even if your gut doesn't think so.”
---
[01:00:19](https://www.youtube.com/watch?v=taaEzHI9xyY&t=3619s) Q&A: Formatting Tools and CoffeeScript
Following applause, Crockford opens the floor to audience questions:
- **JS Tidy Tool**: Felipe Gasper asks whether a tool exists for JavaScript comparable to Perl Tidy—specifically, a utility that automatically finds a `var` declared in the middle of a function and hoists it to the top so developers do not have to manually edit the top of the function. Crockford replies that while someone may have created one, he hasn't; he notes that for a long time he considered writing a tool called "JSMax" as the reverse of JSMin to expand and normalize code, but never built it. - **CoffeeScript**: An audience member asks for his thoughts on CoffeeScript. Crockford responds enthusiastically, stating: “I really like CoffeeScript.”
[01:01:15](https://www.youtube.com/watch?v=taaEzHI9xyY&t=3675s) Perspectives on CoffeeScript
Douglas Crockford shares his evaluation of CoffeeScript, praising its conceptual goals while maintaining caution regarding its use in enterprise software. He explains that JavaScript’s genuine virtues have nothing to do with its syntax, which he considers quite awful and responsible for the majority of the language's worst parts. CoffeeScript, by contrast, identifies JavaScript's underlying good parts and overlays them with a clean, minimal syntax. While Crockford finds this achievement impressive and expresses genuine fondness for CoffeeScript, he does not advise adopting it in production environments because it introduces its own distinct set of tooling and language problems that disrupt the overall tradeoff.
Looking forward, Crockford notes that he would love to see the JavaScript language itself evolve in the direction pioneered by CoffeeScript over the long term. However, he remains skeptical that the ECMAScript standards bodies will realize this vision given the competing industry pressures surrounding the evolution of the language.
> “CoffeeScript takes the good parts and puts a minimal syntax on top of it, which is lovely.” — Douglas Crockford
[01:02:03](https://www.youtube.com/watch?v=taaEzHI9xyY&t=3723s) Critique of Google Dart
An audience member prompts Crockford for his perspective on Google Dart, Google's newly introduced structured web programming language. Crockford initially mishears the question before giving an unsparing assessment. He reflects that if he were granted a clean sheet of paper to engineer a replacement language that eradicated every defect in JavaScript while preserving all of its core brilliance, the result would look nothing like Dart. In his view, Dart abandons what makes JavaScript truly expressive and compelling, regressing instead toward the conventions of Java.
Crockford does not mince words regarding Dart's surface design, dismissing its syntax as poor and expressing bewilderment at why Google's engineering team chose this route. He jokes that despite the substantial number of engineers inside Google championing Dart as a sound direction, he simply cannot comprehend the rationale behind the project.
> “It feels like it's trying to go back and be more Java-like.” — Douglas Crockford
- Dart fails to retain the inherent goodness that makes JavaScript powerful despite its flaws. - Crockford views Dart's syntax as a major step backward rather than an improvement. - He notes with amusement and dismay that many engineers inside Google believe Dart is the right answer for the web platform.
[01:03:08](https://www.youtube.com/watch?v=taaEzHI9xyY&t=3788s) Language Minimalism and the Essence of JavaScript
When an audience member asks if there are other programming languages whose features should be borrowed to enhance JavaScript, Crockford rejects the entire premise of expanding the language. He argues that JavaScript should be shrinking rather than expanding. He reveals that his personal aspiration for the next edition of the ECMAScript standard was to render JSLint obsolete by eliminating historical hazards; however, he concedes that committee dynamics make this impossible. Instead of pruning, committee efforts inevitably add substantial surface area, which will inadvertently introduce new "bad parts" because rapid language expansion always brings unintended traps.
Crockford reflects on the accidental genius of JavaScript's original synthesis. Brendan Eich miraculously married first-class functions and lexical closures from Scheme with the dynamic, prototypal inheritance model of Self, wrapping those two deeply experimental ideas in a familiar, C-style syntax that managed to work. Crockford emphasizes that this core foundation is already sufficient to express almost any computational pattern, insisting that any capabilities beyond that base should be supplied as userland libraries rather than hardwired into the language specification itself.
> “I'm not an advocate of trying to make JavaScript bigger.” — Douglas Crockford
```mermaid flowchart TD accTitle: JavaScript Core Synergy versus Feature Expansion accDescr: Diagram illustrating JavaScript's core foundations combining Scheme and Self concepts versus Crockford's warning against adding language bloat.
subgraph Core["JavaScript's Ingenious Core"] A["Scheme Concepts<br/>First-class functions & lexical closures"] B["Self Concepts<br/>Dynamic objects & prototypal inheritance"] C["Mainstream C-Style Syntax"] A & B --> C end
subgraph Evolution["Language Evolution Paths"] D["Userland Libraries<br/>(Preferred path for additions)"] E["Language Bloat / New Bad Parts<br/>(ECMAScript committee expansion)"] end
C -->|"Sufficient Foundation"| D C -.->|"Unnecessary Standard Bloat"| E ```
[01:04:27](https://www.youtube.com/watch?v=taaEzHI9xyY&t=3867s) Unfiltered `for...in` Loops and `hasOwnProperty`
Audience member Felipe Gasper challenges Crockford on JSLint's strict enforcement against unfiltered `for...in` loops, questioning why iterating without an explicit `hasOwnProperty` check is flagged as an error. Gasper argues that this requirement actively undermines the utility of prototypal inheritance. He points out that UI frameworks like YUI reject configuration settings inherited through prototype chains because of this exact philosophy, making it frustratingly counterintuitive to leverage prototype chains for configuration objects. Gasper even notes that standard methods like `Object.keys` reflect this restrictive mindset.
Crockford pushes back firmly, explaining that excluding inherited properties is an intentional defense against genuine hazards rather than an architectural oversight. While he concedes that engineers can invent clever, valid use cases that exploit inherited properties inside loops, the construct remains inherently error-prone and brittle across unpredictable execution environments. For Crockford, safety and predictability always outrank syntactic cleverness.
> “The reason that I'm recommending you not use it isn't because you can't figure out a clever use for it -- I admire you for having found a clever use -- I still recommend you not do it.” — Douglas Crockford
- Felipe Gasper highlights that YUI strips out inherited configuration options due to internal prototype filtering. - JSLint insists on wrapping every `for...in` enumeration with a `hasOwnProperty` guard to prevent runtime leakage from modified prototypes. - Crockford maintains that even if a developer discovers an ingenious pattern relying on prototype inheritance during enumeration, the universal hazard of unexpected properties justifies the blanket prohibition.
[01:05:39](https://www.youtube.com/watch?v=taaEzHI9xyY&t=3939s) Scoping Quirks in `catch` Clauses and Closing Remarks
An audience member asks why JSLint requires developers to use unique variable names across distinct `catch` blocks within the same function. Crockford explains that although the ECMAScript specification intends for every `catch` block to create its own isolated lexical scope, several legacy web browsers implement broken scoping models. Instead of treating each catch parameter as an isolated, block-scoped binding, these faulty browser engines hoist or conflate the identifiers across the function.
Crockford explains that using the identical variable name—such as `e` or `err`—in multiple `catch` blocks within the same function causes those disparate blocks to bind to the exact same shared variable under the hood in broken browsers. To prevent programmers from relying on nonexistent scope isolation and walking into confounding bugs, JSLint requires explicitly distinct names for each exception parameter. Having answered the final question, Crockford concludes the keynote, thanking the attendees, advising them to travel home safely, and bidding everyone good night amid warm applause.
> “If they all have the same name they are all the same variable, and that is a confusion, and we don't want to be confused.” — Douglas Crockford
## Notable quotes > [55:05](https://www.youtube.com/watch?v=taaEzHI9xyY&t=3305s) Computer programs must be perfect and humans are not perfect, so that is the struggle; that is the core problem in our craft. — Douglas Crockford
> [57:35](https://www.youtube.com/watch?v=taaEzHI9xyY&t=3455s) I decided that forms that can hide defects are themselves considered to be defects. — Douglas Crockford
> [36:43](https://www.youtube.com/watch?v=taaEzHI9xyY&t=2203s) Confusion is what causes bugs and security mishaps and all the other things that make us miserable. — Douglas Crockford
> [00:05](https://www.youtube.com/watch?v=taaEzHI9xyY&t=5s) The consequence of fearing the wrong things is that you actually put yourself in greater danger. — Douglas Crockford
> [02:53](https://www.youtube.com/watch?v=taaEzHI9xyY&t=173s) The things that the gut tells the head are weighed as more important than things that the head itself has experienced. — Douglas Crockford
> [10:59](https://www.youtube.com/watch?v=taaEzHI9xyY&t=659s) It is the programmer's fault for having created a program that was not perfect. — Douglas Crockford
## Mentioned Douglas Crockford, Yahoo!, YUIConf, Daniel Gardner, The Science of Fear, Brendan Eich, JSLint, Vaughan Pratt, comp.lang.javascript, Ken Thompson, Dennis Ritchie, B (programming language), C (programming language), C++, Java, Bell Labs, FORTRAN, Emperor Constantine, Johannes Gutenberg, Gutenberg Bible, William Strunk Jr., The Elements of Style, Dave Herman, Felipe Gasper, Microsoft, Google, ECMAScript, JSMin, Perl Tidy, CoffeeScript, Google Dart, Scheme, Self, ALGOL 60, Internet Explorer (IE6, IE7, IE8, IE9, IE10), YUI
## Video description In this keynote talk from YUIConf 2011, Yahoo! JavaScript architect Douglas Crockford drops some science to explain why code style is important in programming -- particularly in JavaScript -- and how tools like JSLint can help.
[Source](https://www.youtube.com/watch?v=taaEzHI9xyY)