Crockford on JavaScript - Section 8: Programming Style & Your Brain

Crockford on JavaScript - Section 8: Programming Style & Your Brain — YUI Library

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)

中文简报

克罗克福德论JavaScript - 第8部分:编程风格与你的大脑 道格拉斯·克罗克福德探讨了史前人类本能与软件开发中对完美的严苛要求之间的神经机制错位。借助系统1(“直觉”)和系统2(“理智”)等认知概念,他阐明了程序员为何经常误判风险并陷入认知盲区。他梳理了从B语言、C语言以及早期JavaScript中继承的历史设计缺陷,展示了模糊语法、自动分号插入、switch穿透以及动态作用域如何滋生出隐蔽且灾难性的错误。最终,克罗克福德主张对JavaScript进行有节制的子集化,并严格采用通过JSLint强制执行的防错规范,以保护开发者免受自身进化缺陷的危害。 道格拉斯·克罗克福德认为,人类的认知架构——特别是快速、依靠模式匹配的“直觉”在进化中对分析性推理的主导地位——使得程序员在天性上难以胜任软件对绝对完美的要求。 (2:53) JSLint的设计哲学确立了这样一种观点:凡是能够掩盖缺陷的语法形式本身就是缺陷,需要依靠自动化规范来克服开发者的防卫性合理化心理。 (57:35) JavaScript的自动分号插入机制将看似属于审美层面的排版选择(例如在return语句后的新行放置左大括号)变成了默默返回undefined的隐形运行时错误。 (18:42) 克罗克福德主张围绕JavaScript的根本优势——Scheme风格的函数和Self风格的原型——对该语言进行积极的子集化裁剪,而不是用复杂的特性扩展语言,或采用类似Java的替代方案(如Google Dart)。 (63:08)

Source quotes

[55:05] Douglas Crockford: Computer programs must be perfect and humans are not perfect, so that is the struggle; that is the core problem in our craft. [57:35] Douglas Crockford: I decided that forms that can hide defects are themselves considered to be defects. [36:43] Douglas Crockford: Confusion is what causes bugs and security mishaps and all the other things that make us miserable. [0:05] Douglas Crockford: The consequence of fearing the wrong things is that you actually put yourself in greater danger. [2:53] Douglas Crockford: The things that the gut tells the head are weighed as more important than things that the head itself has experienced. [10:59] Douglas Crockford: It is the programmer's fault for having created a program that was not perfect.

Original transcript

[0:05] >> DOUGLAS CROCKFORD: Thank you very much. [0:06] Welcome to the YUIConf Gala Costume Masquerade. [0:12] It's great to see all of you here in your festive costumes; you all look fabulous. [0:19] We are here at YUIConf at Yahoo!'s -- where are we? [0:24] -- Great America campus in Santa Clara, California. [0:27] Tonight: Section 8, JavaScript Programming Style and Your Brain. [0:33] This might seem three unusual things to talk about in one talk -- how could these things [0:39] possibly be related to each other? [0:42] JavaScript and brains? [0:43] What's the connection? [0:45] There actually is a connection. [0:47] JavaScript and programming style and brains? [0:50] Yeah, there's a connection and it's an important connection, and surprisingly and hopefully [0:54] entertaining. [0:56] This talk comes from a scientific discovery. [1:00] There were some social scientists who were doing some work, as they do, in trying to [1:04] understand human intelligence. [1:06] How do we think? [1:08] How do our brains work? [1:10] They came up with a set of simple experiments and their results were really surprising. [1:17] They published their results and the scientific community said that can't be right, there [1:22] must have been an error in the design of the experiments, there must have been some error [1:26] in the evaluation of the data. [1:28] This cannot possibly be the correct explanation for how we think. [1:34] But the results were at least interesting enough that other people attempted to replicate [1:38] the studies, and then did follow on studies and new experiments. [1:43] The conclusion was: yeah, it's true, we actually think like this. [1:48] This is sort of how science works, where someone will come up with an experiment which has [1:52] a conclusion which contradicts what is commonly understood by the scientific consensus, and [1:58] it will immediately be challenged. [1:59] But then we'll try to replicate it, and if it bears out then the scientific consensus [2:05] changes to adopt that, until further experiments will contradict again. [2:11] Then there's a Nobel Prize. [2:12] All of that happened in this case. [2:14] This is how science happens. [2:18] This is all told in a wonderful book: The Science of Fear by Daniel Gardner. [2:24] Gardner talks about this research and its implications on society, and the fact that [2:30] because of the way we think, we tend to misunderstand what danger is. [2:36] We fear the wrong things. [2:38] The consequence of fearing the wrong things is that you actually put yourself in greater [2:43] danger. [2:44] Great book, I highly recommend it. [2:46] What was this discovery that was so amazing and unusual and probably true? [2:53] It was that there are two systems in the brain. [2:58] System two could be called the head. [3:00] It's where we do analytical thinking, it's where we do arithmetic and mathematics. [3:05] It's where we think deep thoughts. [3:10] It's great, but the problem with it is it's kind of slow. [3:14] It's because the head is kind of slow that we had to invent computers, because the modern [3:19] world demanded a lot of number crunching, and we're just not very good at that. [3:25] We needed machines that were faster than we were at doing that stuff. [3:30] Then there's system one, which could be called the gut. [3:33] It's evolved from the flight or fight response. [3:37] It is very, very fast, but there are tradeoffs in the way it's fast, so it makes mistakes. [3:46] If you ever saw a cat just standing there and then suddenly he freaks out and runs, [3:50] and then he stops and goes yeah, I meant to do that, that's the flight or fight response. [3:58] The biases in that system are set so that false positives are OK, because it's better [4:03] to get a false positive than a slow positive, because then you don't have time to get out [4:07] of the way of whatever's at you. [4:09] You'll see a flock of birds suddenly take off for no reason and come back; that's that [4:13] mechanism. [4:14] We got that. [4:16] The gut is really fast, but it's only approximate because it doesn't know arithmetic, it can't [4:22] solve hard problems. [4:24] But it's not trying to solve hard problems, it's just looking for certain kinds of patterns, [4:28] and when it sees those patterns it reacts. [4:31] Now, neither the head nor the gut are surprising. [4:35] I mean, we all know about that. [4:37] My head tells me this but my gut tells me that. [4:40] We're always experiencing that kind of stuff. [4:43] The surprise in this research was the connection between those two systems. [4:48] It turns out that the gut informs the head. [4:51] The gut sets up the assumptions that the head is going to use in doing its computation. [4:58] The head is not generally aware that that's the case. [5:02] The things that the gut tells the head are weighed as more important than things that [5:07] the head itself has experienced. [5:11] That makes it really easy to confuse people by confusing their guts. [5:17] This was news to the scientific community, but there is another community which has known [5:21] about this stuff for a long, long time, and that is of course the advertising community. [5:29] They figured this stuff out decades ago; this is not news to them, because a lot of their [5:35] business is selling stuff to us that we don't need. [5:39] They create wants for things that we don't really want. [5:43] How do they do that? [5:44] You don't do that by talking to the head, you do that by talking to the gut, and nobody [5:48] is better than the tobacco industry. [5:51] Because look at tobacco. [5:54] What does tobacco do? [5:56] It makes you smell bad. [5:58] From the first time you light up, you stink. [6:02] Tobacco does that. [6:04] Then your teeth turn yellow. [6:06] Then you get sick, and then you die. [6:10] That's what tobacco does. [6:11] So how do you sell a product like that? [6:15] You don't sell it to the head, you sell it to the gut. [6:25] If you ask a smoker "why do you smoke?" [6:27] Well, why, that's an analytical question, so that goes to the head. [6:32] But the head is going to now start thinking with facts that it got from the gut, and the [6:37] gut says cigarette smoking is not dangerous because of the way the gut looks at danger; [6:43] it's looking at immediate danger, it's looking at shocking danger. [6:48] Slow death doesn't register. [6:51] So slow death is as good as good for you. [6:59] If you have any logical system and you start with false premises, you can reach a false [7:05] conclusion. [7:06] I mean, we know that; logic tells us that. [7:08] But that's how we think. [7:11] You can ask a smoker "why do you smoke?" and you can be sitting with them in a restaurant [7:16] and if he were rational he'd go "I smoke, well that's stupid, I should stop immediately." [7:23] But that's not what happens. [7:24] Instead he's trying to think "why do I smoke? [7:26] There must be good reasons for it. [7:28] Um, it makes me popular." [7:30] And he'll say that not noticing that the healthy good smelling people who are near him are [7:35] trying to get away so he doesn't taint his food. [7:44] So people will smoke until it kills them, until they die. [7:52] You could say that's because of nicotine addiction, they're addicts and that's why it happens, [7:57] but that doesn't explain brand loyalty. [7:59] Most smokers will stick with the brand that got them hooked until it kills them. [8:05] That's not addiction, that's something else. [8:07] That's some confusion that's happening in the gut. [8:12] Let's switch for a minute and talk about computer programs, a completely different topic. [8:19] Computer programs are the most complicated things humans make. [8:23] We don't make anything else which is as complicated as programs. [8:27] Programs are made of a large number of parts, usually expressed as statements or variables [8:32] or functions or other things, and they all have to work together in a way which is amazingly [8:42] complicated. [8:43] There's nothing we do that's more complicated than software. [8:45] You could point at systems which are very complicated, like an airplane is very complicated, [8:50] and that's true, but the most complicated component in an airplane is the software. [8:57] That's true of all systems today. [8:59] Software is complicated. [9:02] People are not good at that, so early on when we started programming there was this idea [9:06] that programming is just too difficult and we should write programs that can write better [9:11] programs than we can, because people are just not very good at this. [9:17] Once we can get the program to do that, we can then tell the programs "make a program [9:21] that's better than you," and we keep doing that until they become our overlords. [9:32] That didn't happen. [9:33] Artificial intelligence failed. [9:34] Artificial intelligence has done a lot of amazing things -- it can play grand master [9:39] chess and a pretty good game of Jeopardy now -- but you can't give a set of requirements [9:44] and custom router views to a computer and have it write the program for you. [9:50] It can't do that. [9:52] We're still writing programs by hand. [9:55] We've made extremely small progress in the evolution of technological thinking around [10:01] programming. [10:04] The most powerful tool we have is the programming language. [10:09] That is a partnership between us and the computer where it's doing some of the work and we're [10:14] doing some of the work. [10:16] The programming language allows us to work at a higher level of abstraction, which allows [10:20] us to be more productive, but still it's basically handmade stuff. [10:27] Programming languages are extremely important in that they control, or shape, the way that [10:31] we think about things. [10:33] Sometimes that's a really good thing if the programming language helps us to organize [10:37] things well, but that can also create blind spots in us. [10:41] If you're using a programming language that does not offer recursion, you're not aware [10:45] of what a valuable tool recursion is. [10:47] Or if you have a language that doesn't have closures, you're not aware of what a valuable [10:52] tool closures are. [10:54] So, programming languages work for us and against us. [10:59] The thing that makes programming so difficult is that it has to be perfect. [11:03] A program has to be absolutely perfect in every detail for all possible inputs and all [11:10] possible uses, even including uses which were not anticipated in the design of the program. [11:15] If any flaw is found in the program, the computer has license to do the worst possible thing [11:24] at the worst possible time, and it is not the computer's fault. [11:32] Whose fault is it? [11:33] It's the programmer's fault. [11:35] It is the programmer's fault for having created a program that was not perfect. [11:41] You would think that the way we should do this stuff is we should hold onto the programs [11:45] and keep working on them and refining them and cleaning them until finally they are perfect, [11:49] and then we'd release them. [11:51] We don't do that because we would never release anything. [11:57] Instead we put out stuff which is known to be imperfect and just hope that we get away [12:01] with it, that we won't find a bug in it until the next cycle. [12:05] Sometimes we get away with that, and very often we don't. [12:07] So we have this problem of perfection. [12:10] Humans are terrible at perfection. [12:12] We are greatly imperfect creatures. [12:15] I am a very imperfect person, but I program because we've got no one else to do it. [12:23] We are hunters and gatherers. [12:25] I don't mean that metaphorically. [12:26] There has been no human evolution since the Paleolithic era. [12:30] We are those guys, we've got their brains. [12:33] We were selected for running around, our heads were designed for thinking about strategies [12:39] for getting food, and our guts were designed to get us out of danger when the predators [12:44] were coming after us. [12:45] We're using that brain now to program computers, and there is no reason to think that that [12:51] should work. [12:56] Somehow it does. [12:57] It's miraculous, it's crazy. [13:02] We're using everything we got. [13:05] Obviously we're using our head to do the analytical stuff, and it can do it. [13:09] It needs to keep the problem and the state of the program and all of the stuff it's working [13:14] on. [13:15] You try to keep the whole model in your head so you can reason about it. [13:18] But if you try to teach programming, it's really hard. [13:22] We don't have an algorithm for how we do it. [13:25] As we're decomposing a problem, sometimes we're going top down, sometimes we're going [13:29] bottom out, inside out, outside in. [13:31] We're constantly changing strategies as we're working on this. [13:35] Nobody can describe how we do that. [13:39] Somehow we all figured it out, and we do that every day, but we don't know how we do that. [13:45] It occurs to me that it must be the gut that's allowing us to do that. [13:49] It's the thing that shifts us from one strategy to another, that gives us the occasional flash [13:54] of insight which makes the whole thing work. [13:57] We could not program without our gut. [14:01] I have absolutely no evidence to justify that statement. [14:07] But my gut tells me it's true, so I believe it. [14:12] Much of the craft of programming is making tradeoffs. [14:18] There's never a perfect solution to anything, which is one of the things that makes perfection [14:22] unattainable, so we're constantly having to tradeoff space for speed, or other things. [14:28] The gut, unfortunately, is extremely bad at making tradeoffs. [14:35] Sometimes the gut, instead of helping us, significantly hinders us. [14:40] We'll talk about some of the consequences of that. [14:44] The programming language I'm going to use for examples tonight is JavaScript, obviously, [14:52] but the things I'm going to talk about are applicable to all programming languages. [14:56] It's just JavaScript is kind of special, partly because it has good parts. [15:01] I can tell you that I discovered that JavaScript has good parts, and that was the first important [15:07] discovery of the 21st century. [15:14] Everybody has discovered for themselves that JavaScript has really bad parts. [15:19] JavaScript was designed in about ten days, and somehow in those ten days Brendan Eich [15:27] managed to get some good parts in it -- and they are really, really good -- but he got [15:32] a lot of bad stuff. [15:33] There was just not time to try it out and make sure it worked right, and it doesn't, [15:37] and it's horrible. [15:41] My first couple of years working with JavaScript were extremely painful, partly because I decided [15:46] not to learn the language before I started working in it, which was about as stupid a [15:51] thing as you could do. [15:52] I did that. [15:55] But I kept running into all these sharp edges that the language had, so I decided I needed [15:59] to make a tool to help me manage this crazy language. [16:03] I created something called JSLint. [16:05] I started with a Pratt parser. [16:09] Pratt parsers are amazing things. [16:12] You can write compilers really efficiently. [16:16] It's a lovely technique. [16:17] I owe you a talk on that, because it's fascinating. [16:21] Just a little bit of fluff, and suddenly you've got a compiler. [16:23] It's great stuff. [16:27] Having this JavaScript compiler written in JavaScript, I decide to make a Lint tool out [16:32] of it to help me find problems in my programs, because there were a lot of them. [16:37] I started hanging out on comp.lang.javascript, which was on Usenet. [16:43] Anybody remember Usenet? [16:46] Yeah. [16:48] People would come on and say "hey, my program doesn't work," and they'd post it. [16:52] I'd take it and throw it in JSLint and see if I could automatically figure out what the [16:56] problem was. [16:57] Sometimes I could and sometimes I couldn't; sometimes the way they were coding was just [17:01] so complicated or so error-prone that there was no way that you could tell if it was right [17:06] or wrong. [17:08] In cases where these examples suggested rules, I'd put them into JSLint. [17:14] In examples where there weren't, sometimes it suggested a discipline, that if you had [17:19] a discipline then it would be possible to determine if that was right or wrong. [17:25] The program evolved that way. [17:26] When I started I had no plan for how JSLint was going to grow; it basically grew in response [17:33] to the things I was learning on comp.lang.javascript. [17:36] JSLint comes with a warning: JSLint will hurt your feelings. [17:41] This is true, this is absolutely true. [17:43] I hear from people all the time "waaaah, JSLint..." [17:49] You wouldn't believe how much mail I get from people whining about JSLint. [17:54] Well, wait a minute. [18:00] Let's look at this. [18:01] JSLint is a code quality tool. [18:03] Its intention is to help people become slightly more perfect in their programming. [18:08] They're running the program on purpose, for that purpose. [18:10] Why are they complaining that it's telling them how to make their programs better? [18:16] I think there's some interference going on with the gut, that the gut is telling them [18:20] they're doing things which are bad. [18:23] I determined these things were bad empirically by looking at bad programs and trying to identify [18:29] flaws in bad programs. [18:32] They haven't been through the process that I have, so they just don't understand why [18:37] JSLint is telling them to do the things they're doing. [18:42] We've talked about this argument. [18:43] Should curly braces be on the left or the right? [18:46] When Ken Thompson designed the B language he decided to put them on the right. [18:52] They could be anywhere. [18:55] When the late Dennis Ritchie did the C language he copied Thompson's syntax, so he put them [19:02] on the right too. [19:03] But there were guys in their lab who wanted to put them on the left because they thought [19:06] it looked better. [19:08] They probably argued about that for a week and then said leave us out of this, because [19:12] this is a stupid argument. [19:16] There is no reason for why you should do it one way or the other. [19:21] There isn't. [19:22] There is no argument which is right or wrong; left or right, it's completely arbitrary. [19:27] It's like driving -- should we drive on the left or the right? [19:32] The British can demonstrate that you can drive on the left. [19:36] We drive on the right. [19:38] It's OK. [19:39] It's good there aren't any roads connecting us with England so we don't have to deal with [19:43] that. [19:44] It doesn't matter which side we're on, it's just that we all be on the same side. [19:49] I told that story in Bangalor, and it was like confusion; "what is he talking about?" [20:02] If you have someone who's always put them on the left come into a shop where they put [20:06] them on the right, and they say you've got to put them on the right now, he'll start [20:09] to cry. [20:12] "No, I'm not going to put them on the right, that's so wrong. [20:16] Can't you see how wrong that is?" [20:18] He'll start making up reasons. [20:20] The head is now working, trying to figure out why it's wrong. [20:24] "It's more readable?" [20:28] He gets more frustrated because it doesn't make any sense, and he might even hear himself [20:35] saying these things and know this doesn't make any sense, but there's got to be a reason, [20:39] because why would I be this passionate, why would I be crying, if this weren't important? [20:44] We'd like to think we're rational. [20:47] We're programming computers, we're analytical, we're mathematicians, we're laying this stuff [20:52] out, and we're crying because we had to move a piece of punctuation from one line to another. [20:58] There is something else going on here. [21:02] Ultimately, I don't know what the right answer is, except in JavaScript where in fact we [21:07] have a right answer. [21:09] You want to put them on the right. [21:10] You've got to be consistent, no matter what you do. [21:15] Everybody will agree that it looks stupid to sometimes put them on the left, sometimes [21:18] put them on the right. [21:19] You've got to be consistent. [21:20] It's like driving. [21:21] You've got to always do it the same way, and everyone will agree that everybody should [21:24] do it like they do it. [21:27] But we can't agree on how it should be. [21:29] I think Thompson did the world a disservice. [21:32] He could have easily fixed his B compiler and said it's got to be on the right, dammit, [21:35] and shut up or you get a syntax error, end of story. [21:38] But he didn't, he left it sloppy. [21:41] That introduced some personal expression into the thing, so we can't agree. [21:47] Partly we can't agree because there isn't a right answer, except in JavaScript, because [21:52] of semicolon insertion, which does this stupid thing if you have a return statement that's [21:57] returning an object literal instead of returning an object, it returns undefined. [22:03] You get no compile time warning, no runtime warning. [22:07] Your program may not fail at the point here; it may fail some minutes later, which makes [22:12] debugging really hard. [22:14] In debugging if you finally track it down to this line, you can look at that for hours [22:19] and not understand what's wrong with that. [22:21] That should work. [22:23] This is due to a terrible design error in JavaScript. [22:27] This was a blunder, it's awful. [22:31] But if you always put your curly braces on the right, you will never suffer. [22:44] Once after explaining this at a talk, someone came up to me and said "wow, that thing about [22:48] the return statement, that is so right. [22:51] From now on on all my return statements I'm going to put them on the right, but the rest [22:54] of the time I'm still going to put them on the left." [23:02] Prefer forms that are error resistance. [23:05] For no cost, if you just say I'll do this thing for which there isn't a right answer [23:10] and do it this way, you avoid a terrible problem, and the net cost of doing that is zero. [23:18] If you look at it in terms of tradeoffs, this is a good tradeoff. [23:22] For zero cost, big benefit, you're trying to be perfect? [23:27] This is good. [23:29] Your gut might be saying no, this is so wrong, can't you see how wrong this is? [23:33] The gut is really bad at making tradeoffs, but the gut will tell the head yeah, we're [23:38] making a good tradeoff. [23:40] But you're not. [23:44] The switch statement. [23:45] I have to tell the switch statement story again. [23:47] Early in the development of JSLint someone wrote to me and said "you know, there's a [23:52] problem with the switch statement." [23:53] The switch statement was designed by Thompson. [23:56] He modeled it after the Fortran computed goto statement, which is now recognized as harmful. [24:02] But that hadn't been completely accepted yet. [24:06] There's this goto-ness in it, in which you really don't have a set of cases, you've got [24:11] a set of labels and the code will fall through to each other. [24:15] It's really a computed goto statement, which is terrible. [24:20] You can have fall-through going on. [24:23] This guy wrote to me and said "that's sometimes a problem. [24:26] When I'm looking at the code it's really hard to see where the fall through occurs, and [24:32] that can be a difficult thing to debug, so your Lint program should warn about that." [24:36] I thought about it, and I wrote back to him, I said "well yeah, that's true, I've seen [24:41] it, but that hardly ever happens. [24:43] On the other hand, you can optimize the flow going through all these cases and that could [24:50] be quite elegant. [24:52] There's value in that, so looking at the tradeoff, I think it's probably better not to warn on [24:57] that." [24:58] OK. [24:59] The next day, the same guy wrote to me and said he found a bug in JSLint. [25:02] I'm always happy to hear of that, so I threw the debugger, and it turned out I had a case [25:07] that was falling through. [25:09] In that moment, I achieved enlightenment. [25:16] We like to think we spend most of our time power typing. [25:19] "Yeah, I'm being productive, I'm writing programs!" [25:23] But we don't. [25:24] We spend most of our time looking into the abyss, saying "My God, what have I done? [25:30] How am I ever going to make this work?" [25:34] Once we figure it out, we forget that we did all of that. [25:39] It's sort of like the way we forget the false positives that the gut triggers. [25:44] If we observe all of the false positives then the gut couldn't work anymore, because we'd [25:48] be analyzing our reactions instead of responding, which is what the gut wants us to do. [25:57] I got that really wrong. [25:59] What was my mistake? [26:02] That hardly ever happens means the same thing as it happens. [26:08] This is the gut talking, and the gut is confused about number. [26:12] The gut thinks that a lot has more value than all. [26:17] The gut thinks that not very much, or not very often, is the same as none, or never. [26:23] That's not true; I mean mathematically we know that's not true, but the gut tells us [26:27] that. [26:28] So that caused me to reach a very wrong conclusion about the safety of switch statements. [26:36] Normally when we make mistakes we just forget about it and keep going. [26:40] We spend most of our time making mistakes, not power typing, because there's something [26:46] wrong with us. [26:49] I used to think that everybody should learn programming when I first started learning [26:53] it and thinking about how to organize the world in terms of data structures and algorithms. [26:57] I thought wow, this is such an amazing way to organize information -- everybody should [27:02] learn to do this. [27:03] I don't think that anymore. [27:05] I think there has to be something seriously wrong with you in order to do this work. [27:09] A normal person, once they've looked into the abyss, would say I'm done, this is stupid, [27:18] I'm going to go do something else. [27:20] But not us, because there's something really wrong with us. [27:29] A good style can help produce better programs. [27:32] Style should not be about personal preference or self-expression. [27:36] Some people think that style is the stuff in your program that the compiler ignores, [27:41] and because the compiler ignores it, you've got license to do whatever you want with that [27:45] because it doesn't matter, it's not part of the important information. [27:49] You can structure it any way you want, just to show off or to amuse yourself or to express [27:56] your individuality. [28:00] That's not what it's for. [28:02] Let's talk about style. [28:07] The Romans wrote Latin all in uppercase with no word breaks or punctuation. [28:12] They were the biggest empire in the world at one time, and they did fine with this. [28:23] It's definitely harder to read from our perspective. [28:26] Like, on the third line, you could read that as "NOW OR DB REAKS". [28:30] You have to work a lot harder in order to parse the text and understand what it says. [28:38] This worked fine for the Romans up until about the time Constantine established Christianity [28:43] as the state religion of the Roman Empire. [28:46] At that point it became necessary to replicate all of the Holy documents and distribute them [28:51] over the empire. [28:52] There was a problem, because they didn't have the originals of any of these documents; all [28:57] they had were copies of copies of copies, and none of the copies agreed. [29:02] That was a problem because they were claiming their spiritual authority on the written word, [29:08] and nobody was really sure what the written word said. [29:14] They decided well, we need to get better at this. [29:17] It turned out this style of writing was contributing to the problem. [29:21] This turns out to be really hard to copy by hand accurately. [29:27] Medieval copyists introduced lower case, word breaks, and punctuation in order to improve [29:34] their error rate. [29:36] It made it easier to extract the information from the texts and to copy them into good [29:43] copies. [29:45] It worked -- this was a very effective way of making their copying much more reliable. [29:51] Gutenberg copied this convention when he laid out his Bible, and it's been in printing ever [29:55] since then. [29:56] It's on the internet now. [29:57] This is the way we do text, not just in religious texts now but in academic work, popular work, [30:04] fiction; everything uses these conventions because they work. [30:08] We've been using these now for many centuries. [30:10] It's a good idea, and I think to the extent it makes sense, we should continue to use [30:15] these in programming too, because the most important thing for a program is for people [30:19] to understand it. [30:21] This is a convention that people can understand. [30:24] We have centuries of evidence about it. [30:27] But what they demonstrated was that use of good style can help reduce the occurrence [30:33] of errors. [30:34] Since we're going after perfection, we want a style which helps us to do that. [30:39] There have been lots of books written about style in literature. [30:43] One of my favorites is William Strunk's Elements of Style. [30:47] It's very influential. [30:48] It was written almost one hundred years ago. [30:52] Some of his advice is a little dated now, just because English has continued to evolve [30:57] as a language, but much of his advice is still really, really good. [31:04] Programs must communicate to people. [31:06] There are some people who think as long as the compiler understands what I meant, that's [31:10] all that matters. [31:11] That may be the least important thing. [31:14] It's more important that humans be able to understand it, because we need to keep that [31:18] thing working. [31:19] Particularly as we get more and more agile, programs are never finished, so you can't [31:22] say it's in the can, it's done. [31:24] It needs to always be in a form which is always editable, and in order to be editable it needs [31:30] to be readable. [31:33] We want to use the elements of good composition where applicable. [31:37] For example, if you have a comma, you put a space after it, not in front of it. [31:42] Even though the compiler will let you put it in front, there's no reason to do that. [31:47] It looks stupid, and you don't want to write programs that look stupid. [31:54] Now, the rules of English are not good enough for software. [32:00] There were attempts at trying to create programming languages which look like English, and they [32:06] didn't work because English is not precise enough. [32:09] You need extreme precision as you're trying to approach perfection. [32:14] The computers are not smart enough to make sense out of wacky prose, so we need to be [32:19] much more specific. [32:22] We have new kinds of ambiguities that we need to be concerned about that we didn't need [32:25] to be concerned about when we were writing in English. [32:29] For example, we've got parentheses which can indicate grouping, and they can also indicate [32:33] invocation. [32:37] One way to help us distinguish which of those is going on is that when we're grouping, we [32:43] put a space in front of it, and when we're invoking we don't. [32:49] In these examples foo is a function, so there should not be a space, it should be adjacent. [32:57] Return is not a function. [32:58] In some languages it could be a function but in JavaScript it's not, so we should make [33:02] it clear it's not a function. [33:03] There should be a space there. [33:05] Here we have an anonymous function, but it looks like we're calling a function called [33:10] function, and that's not what we're doing. [33:12] We should put one more space in there to make it clearer. [33:14] You could argue that the reader ought to be able to figure this out, and in fact the reader [33:20] can. [33:21] You could figure out all these bad examples and make sense out of what was really going [33:24] on, but that is not where the reader should be spending their time and energy. [33:29] They shouldn't be trying to get past your syntax and your lousy grammar, they should [33:33] be trying to understand the thoughts and the structures of the program so they can make [33:36] it work. [33:39] In JavaScript we've recently discovered that immediately invokable function expressions [33:46] are a really useful form, but there's a syntactic hazard in that you can't put them in as the [33:53] first thing in a statement because of an ambiguity in the language. [33:58] If the word function appears in statement position, then that's assumed to be a function [34:04] declaration, and you can't immediately invoke a function declaration. [34:09] I think you ought to be able to, but you can't. [34:11] The way we get around that is by putting parentheses around it, and those parens change it from [34:17] being in statement position to expression position, and then there's no ambiguity; we [34:21] know it's a function literal. [34:25] I see a lot of people wrap the function in parens, but I think that looks goofy. [34:30] What we're talking about is the whole invocation but we've got these things hanging outside [34:35] of it looking sort of like dog balls. [34:43] [laughter] [34:48] So we have an opportunity here to use the weirdness in JavaScript syntax to help the [34:52] reader, saying no, what's important is the whole invocation. [34:56] I would put the parens around it. [34:59] That's better, I think. [35:01] We can see everything between the parens should be treated as a unit, which is the function [35:06] being invoked. [35:07] That's what we're talking about in this expression. [35:09] Now, there's another hazard in the language. [35:12] We've talked before about automatic semicolon insertion. [35:15] Here's another example of that. [35:18] We can have almost any statement before this immediately function and it will be misinterpreted. [35:24] Instead of setting x to y and then doing our function thing, it will treat y as a function [35:32] and pass the other function to it as a parameter. [35:36] That's screwed up. [35:38] This is majorly screwed up. [35:43] The moral of this is: do not rely on automatic semicolon insertion. [35:47] Put all of the semicolon insertions in all of the places where they're supposed to go [35:51] and nowhere else, because if you don't, things like this happen to you. [35:56] This is another thing where you could read this code for hours and go "I don't see what's [35:59] wrong with this." [36:01] If you put it in JSLint it'll tell you right away what's wrong with it, and that's why [36:04] you should pay attention to everything JSLint tells you. [36:09] JavaScript has a with statement, which is terrible. [36:11] It was a nice idea, it was well intentioned, but it just doesn't work right. [36:17] We've got this green with statement. [36:20] It does one of those. [36:22] Can anyone tell me which one it does? [36:24] Yeah, well you can't tell. [36:27] It could do any of them. [36:29] In fact, every time this statement is executed, it could do a different one. [36:34] There's no way you can tell, reading the program, what it's going to do. [36:38] When JSLint's looking at a program trying to figure out what's wrong, it says oh, you've [36:43] got a with statement, that's your problem. [36:50] Stop using those with statements! [36:51] You don't need it. [36:52] There's nothing you can do with a with statement that you can't do just as well without one, [36:57] so just don't do it and you avoid the confusion that this causes. [37:02] Now, some people argue, well yeah, I know with is screwed up, but still sometimes it's [37:09] really useful. [37:10] You can do these really clever, useful things with it. [37:13] I'm not saying it's not useful, I'm saying there isn't ever a case where it isn't confusing. [37:21] Confusion must be avoided. [37:22] Confusion is the enemy. [37:24] Confusion is what causes bugs and security mishaps and all the other things that make [37:29] us miserable. [37:30] We want to be precise and clear and clean and elegant and simple; we don't want confusion. [37:36] We can't afford it. [37:39] JavaScript has a broken double equal operator. [37:41] Brendan knew it was broken. [37:43] When the language was standardized he was trying to fix it in the standardization committee, [37:47] but Microsoft insisted no, it stays wrong in the spec, so we've still got it. [37:56] Fortunately Brendan was able to get triple equal in kind of late, so I recommend to always [38:01] use triple equal and never use double equal, because triple equal avoids these stupidities. [38:07] Now, some people will ask, well, what about in the case where double equal actually does [38:13] what I want? [38:14] Can I use it in that case? [38:16] I'd recommend no, don't even use it then, because someone who's reading your program, [38:21] they have to stop and ask is he using it because this is one of the rare cases where it actually [38:26] makes sense ,or is he just incompetent? [38:29] Which is it? [38:30] Maybe it's undecidable. [38:33] Maybe he's read other things you've written and gone "I don't know." [38:40] So don't use it, because it's hard to tell if it's being used right. [38:45] Anything which is indistinguishable from a common error, if there's a better alternative [38:48] then go with that. [38:50] If there's a feature of the language that is sometimes problematic and if it could be [38:53] replaced by another feature that is more reliable, then always use the more reliable function. [38:59] The cost is zero. [39:01] The benefit is that you avoid a whole class of bugs and confusions. [39:05] Another good tradeoff. [39:09] Multiline string literals. [39:10] This is a new feature in the language; it was added in ES5. [39:14] I don't like this feature for two reasons. [39:17] One is it breaks indentation. [39:20] We have deeply nested structures in our programs, and this breaks it. [39:26] The text has to go all over to the left margin, so it makes the program harder to read, it [39:30] really does. [39:32] But there's a worse problem than that; there's a syntactic problem. [39:36] The first one is OK, and the second one has an error in it. [39:40] Can anyone spot the error? [39:42] Yeah, yeah. [39:46] There's a space here. [39:48] I mean it's obvious once it's pointed out, right? [40:02] But I don't want to be putting things in my program that I cannot distinguish from errors. [40:07] I want my program to be obviously right, or at least obviously trying to achieve rightness. [40:12] I don't want to be putting in things which are clearly wrong. [40:15] That makes it much harder to spot the things that are really wrong. [40:20] So avoid forms that are difficult to distinguish from common errors. [40:22] Some people say "but I did that on purpose! [40:27] I'm intentionally using this thing that looks wrong." [40:30] I don't even have to answer that, do I? [40:32] I mean it's just stupid. [40:33] Often I hear people saying "it's OK because I know what I'm doing." [40:39] If you knew what you were doing, you wouldn't be doing that. [40:48] This is a common bug. [40:50] You see this in most of the C-like languages. [40:55] We've got the first statement, which appears to be doing what that one does, but actually [41:00] does what that one does. [41:03] When you're reading this program you have to stop and ask "OK, which did he mean? [41:11] Did he accidentally get it right, or not?" [41:15] All we know for sure is that the programmer's incompetent. [41:17] Beyond that we really don't know what he's thinking. [41:24] My advice is don't write the top one, write one of these two. [41:27] Figure out which one of these you mean and write that. [41:30] Make it clear. [41:32] We have a problem in JavaScript with scope. [41:34] Well, it's not really a problem. [41:36] Scope is the idea that you've got some block, and anything that's declared, any variables [41:40] declared inside of it, are not visible outside of it. [41:43] That turns out to be a really good thing. [41:44] It came with ALGOL 60, it's one of the great ideas in programming language history. [41:51] Most languages have something that's called block scope where any block defines the scope, [41:56] so any variable you declare inside of that block is not visible outside of the block. [42:01] Nice. [42:02] JavaScript doesn't have that. [42:03] JavaScript only has function scope, which means any variable declared anywhere within [42:07] a function is visible everywhere within the function. [42:12] That turns out to be OK. [42:13] You can write good programs just having function scope. [42:17] The problem is that JavaScript syntax looks like a language that has block scope, but [42:22] it doesn't, so that's confusing for people who learned programming in another language [42:28] like Java or C or C++ or any of those others. [42:32] They come to JavaScript and they get confused about what the visibility of variables are, [42:36] and confusion leads to errors, so that's a bad thing. [42:40] In a block scope language, the advice is to declare the variable as close to the first [42:45] use as possible. [42:46] That's good advice in those languages. [42:49] In a function scoped language, that is really bad advice. [42:52] You should declare the variables at the top of the function, because that's what's actually [42:56] happening anyway. [42:57] Let me show you what's actually happening with a variable statement, with a var statement. [43:02] A var statement gets split into two pieces. [43:07] The var part gets hoisted to the top of the function and initialized to undefined, and [43:14] then the initialization part stays where it is and later gets executed. [43:19] If you declare a variable inside of a block it doesn't get declared inside of a block; [43:23] the declaration part gets hoisted up to the top of the function so it actually gets declared [43:28] at the top, so it's visible everywhere within the function. [43:31] Again, not a bad thing, except the syntax suggests that's not what's happening. [43:38] Because of that confusion, I recommend declaring all of your variables at the top of the function. [43:43] Also, while we're at it, declare all of your functions before you call them. [43:49] JavaScript has these hoisting tricks which allow you to not do those things, but confusion [43:54] happens because most people don't understand how that hoisting happens. [43:58] Even if you understand it the people who are reading your program may not, and you want [44:03] to write the programs so that they can make sense of your work so that they can transform [44:08] your program into something with greater value. [44:11] That's hard if the conventions you were using were causing them to make bugs. [44:19] So make your programs look like what they do. [44:22] Now the thing that seems to be hardest for people to accept is the for var statement, [44:29] where you're declaring the induction variable in the conditional part of the for statement [44:35] in the initialization clause, because that's how you do it in Java. [44:40] I mean, it makes so much sense, but it makes no sense in JavaScript, because that variable [44:47] is not scoped to the loop, and if you do things which are dependent on the scoping of that [44:52] variable inside of the loop, your program will fail. [44:56] It works differently than what you're thinking, and even if you think you understand it, the [45:00] person who's reading your program may not. [45:02] I've seen really good programmers get hung up on this. [45:08] You've just got to tell them you're not working in Java. [45:15] This is not Java, this is a different language. [45:17] Write in the language you're writing in. [45:22] This is a different language; it has different rules, different conventions, different good [45:25] parts, and you need to respect that. [45:30] JavaScript has global variables. [45:31] This is the biggest problem in JavaScript. [45:34] I'm hoping we'll fix it in the next edition. [45:36] Dave Herman will be here tomorrow morning to tell us about some of the stuff we're going [45:40] to do here. [45:41] But for now we're stuck with global variables, and that's a problem because global variables [45:44] are evil. [45:47] They cause all sorts of reliability problems, security problems, really bad things, and [45:51] the language is dependent on them. [45:54] My advice is to avoid global variables as much as possible. [45:57] You should try to reduce your use of global variables in a program or a subsystem down [46:03] to one or maybe zero. [46:04] It's possible to do in JavaScript, which is really nice. [46:07] The language provides for its own workarounds. [46:10] In the few cases where you have to use global variables, I recommend making your global [46:14] variable names all uppercase. [46:17] I want my global variables to be as rare as hen teeth, and I want them to stick out like [46:21] a sore thumb. [46:24] All uppercase seems to be the most obnoxious way you can write a variable name, so that's [46:27] the way I want to write it so it's really clear that this is stupid. [46:38] The biggest resistance I see people having to that is that they come from other languages [46:42] like C where all uppercase means something completely different. [46:45] C has a different class of problems. [46:47] C has a preprocessor, a macro processor on the frontend, and it can create.... [46:53] In the language you can create things that look like variables that are not variables, [46:56] they're macros, and that is a source of confusion. [47:00] People at Bell Labs really early on discovered that confusion was intolerable, so they established [47:05] a convention: let's make all the macros all uppercase, and that way we can tell which [47:09] is which. [47:11] That convention of having consonants be in uppercase traveled over to Java for no good [47:18] reason, because they had finals, so there was no reason to do that. [47:21] But they did it anyway. [47:23] That convention is now coming to JavaScript, where it makes absolutely no sense, because [47:27] we don't even have final. [47:29] It's nothing. [47:31] My advice is let's use that convention for something that has value in this language, [47:38] never mind what it might mean in other languages. [47:42] JavaScript has a new prefix. [47:45] I don't use the new prefix anymore; I found it's just so problematic I don't use it anymore. [47:50] I use object.create now exclusively. [47:53] But some people still use new, so that has to be respected. [47:59] But there's this big problem in the language that if you write a constructor function and [48:03] someone forgets to put the new prefix in front of it, instead of creating and initializing [48:09] the new object it clobbers global variables, which is horrible. [48:14] It's the worst -- maybe second worst -- thing it could do. [48:18] Maybe it could kill somebody; that might be worse. [48:23] So that's a really bad thing. [48:28] Fortunately that gets fixed in ES5 strict. [48:32] Unfortunately ES5 strict is not in IE6. [48:35] It's not in IE7. [48:36] It's not in IE8. [48:38] And it's not in IE9. [48:41] But someday we'll get some value out of ES5 strict, and that'll be good. [48:49] In the meantime we have the InitialCaps convention. [48:53] If a function starts with an InitialCap, we know it has to be used with new, and that [48:59] should be the only use ever of the InitialCaps. [49:02] Having that convention, it becomes possible to read a program and figure out if it's using [49:07] new correctly, if the constructors are being used correctly. [49:11] Without that it's hopeless; there's no way you can read a program and know if it's right. [49:15] So this is an important convention. [49:17] In some languages they don't have this convention. [49:19] Microsoft still hasn't figured this out. [49:22] But it's important. [49:23] This should be respected. [49:26] Here's another fun thing you can do with var statements. [49:30] The top statement appears to mean this, but it actually means this. [49:36] Again, you have to look at it and ask what the intention was here, and again, all you [49:44] really sure know for sure is the programmer was incompetent. [49:48] Again, figure out which of these you meant and write one of those. [49:53] Don't ever write the one on top. [49:57] Write in a way that clearly communicates your intent; that's what we should be doing as [50:02] programmers. [50:05] Someday we may have the let statement in JavaScript, and that'll be nice. [50:09] Let is like var except it respects function scope, so there's no more hoisting, and that'll [50:16] be great. [50:17] When that happens, my advice will change from declare all your vars at the top to saying [50:23] never use the var statement ever again, we're using let from now on. [50:27] But we're not there yet, and we're not going to be there until we get rid of IE6, and IE7, [50:35] and IE8, and IE9, and IE10. [50:47] ++. [50:49] This came out of C. It was intended for doing point arithmetic, so you could increment pointer [50:54] and get to the next thing that was being pointed at. [50:57] We've since determined that point arithmetic is a really bad idea. [51:01] The last popular language with point arithmetic was C++, a language so bad it was named after [51:07] this operator. [51:17] But we still have it, so it's in all of our languages now even though we don't have pointers [51:21] anymore. [51:22] It adds one to something. [51:25] It is generally used to create side effects, and side effects are a source of confusion [51:32] anyway. [51:34] But I've found that when I'm writing stuff with ++, I cannot stop myself from trying [51:41] to pack as much stuff into a statement as I can. [51:45] I'm not the only one. [51:47] A generation of programmers has this affliction. [51:50] Most of the buffer overrun craze in the eighties and nineties, where it was so easy to take [51:55] over operating systems, was because of this operator; it just is so easy for the enemy [52:03] to get something into memory and get it executed because this encourages you to write stuff [52:09] which is just way too damn clever, way too difficult to understand. [52:14] It's bad. [52:15] I've found in my own practice, I do not trust myself to use this operator ever, because [52:21] if I use it anywhere, even in a for statement, I start getting the twitch and I'm trying [52:29] to push too much stuff in, I'm using commas, I'm doing all sorts of stupid stuff trying [52:33] to get it all on one line. [52:35] I'm trying to optimize a thing which has absolutely no value, has negative value. [52:41] There's no cost to us today in getting stuff all into one line and it presents a tremendous [52:48] cost in terms of reliability, readability, all of the good abilities. [52:53] It's a bad thing. [52:55] In my own practice, I say no. [52:57] I do not trust myself to use this ever. [53:00] I use + = 1 instead, everywhere, because I'm no good with the other one. [53:08] I get people complaining "wait a minute, I should be able to write x++ because it's one [53:13] character shorter, and it means the same thing." [53:23] Saving one character here has no value at all. [53:26] It is not a good tradeoff. [53:28] In fact, it doesn't mean the same thing. [53:31] ++x means the same thing. [53:34] This actually means something slightly different, and something slightly different means you've [53:39] got a subtle off by one error that is really hard to detect because it's only off by one [53:44] for a moment, so debugging that is really hard. [53:49] When I see someone using that interchangeably with that, I have to look at every ++ in his [53:54] stupid program and ask OK, did he get it backwards or not? [53:58] Does he understand the difference between pre-increment and post-increment? [54:01] Because he doesn't there. [54:04] I don't have time for that, it's just way too much work. [54:06] I'm just trying to make the program work, I don't want to have to figure out what he's [54:10] doing. [54:12] Recently I was reviewing some code and I saw this: ++x; ++x. [54:21] Now had he originally written x += 1, he could have easily changed that to x += 2 and it [54:28] would have been great, but now it's too much work so he doubled the line. [54:32] Or maybe it was a copy and paste error? [54:34] I don't know. [54:36] I don't know. [54:38] It's stupid. [54:39] I would call a bug on that. [54:40] I don't know that it actually is the wrong thing, but it sure looks stupid. [54:45] It would cause me to wonder if there are other really bad things in this program. [54:52] So for no cost, by adopting a more rigorous style, many classes of errors can be automatically [54:59] avoided. [55:00] That is a good tradeoff. [55:01] No cost, big benefit. [55:05] Here's another one. [55:07] The biggest design error that Thompson made when he designed B -- and Ritchie copied the [55:13] error in C, and everybody's copied it in everything since then except for maybe Python -- was [55:19] that he made the curly braces optional on these structured statements. [55:24] He should have made the parentheses optional, but he decided to make the curly braces optional [55:28] instead, and that was a huge mistake. [55:31] As a result of that you have statements like this, where it looks like we're going to conditionally [55:36] call B and C, but that's not what happens. [55:39] It looks like it wants to do this, but it actually does that. [55:43] This is another one of these confusion things. [55:45] I talk to people all the time saying my advice is put the braces in, put them in everywhere. [55:54] It's only two characters and it makes your programs so much more resilient and it's so [55:57] much more likely that someone who's going to be maintaining your program doesn't accidentally [56:02] break it. [56:03] It makes your program stronger, less error prone, and that's a good thing. [56:07] "But it's two characters! [56:09] So hard!" [56:13] It's not that hard. [56:14] Again, they're thinking we spend all of our time typing. [56:17] If we can somehow save those two keystrokes, we're going to be so much more productive. [56:22] And you're not. [56:23] You're going to be so much less productive because you're going to be chasing down problems [56:27] due to false structures in your code. [56:31] As our processes become more agile, our coding must be more resilient. [56:36] We need to anticipate that this code is going to be changed many, many times, and will not [56:41] break as a result of that change. [56:43] We can't do anything that's too tricky or too intricate, because it will not work. [56:50] Programming is the most complicated thing that humans do. [56:55] Computer programs must be perfect and humans are not perfect, so that is the struggle; [57:01] that is the core problem in our craft. [57:06] That is what we do. [57:09] Designing a programming style demands discipline. [57:12] We're not selecting features because they are light, or pretty, or familiar. [57:17] We're designing features because we want to improve our error rate. [57:22] Now, because we spend way too much time staring into the abyss, if you want to be more productive, [57:31] spend less time staring into the abyss. [57:34] That's what I'm talking about. [57:35] The JSLint style was driven by the need to automatically detect errors. [57:41] I decided that forms that can hide defects are themselves considered to be defects. [57:49] I had no idea I was going to reach that conclusion when I started working on JSLint. [57:54] When I started working with JavaScript, I made exactly the same mistake that everybody [57:59] else makes, so I don't claim to have come into this with perfect knowledge, and I'm [58:05] not trying to impose my personal standard on anybody. [58:09] This all came about empirically as a result of trying to automatically detect errors in [58:13] a deeply flawed language. [58:15] JSLint taught me JavaScript. [58:17] I know what I know about JavaScript because JSLint taught me. [58:21] JSLint is much smarter about JavaScript than I am. [58:25] It's probably smarter than you are, too. [58:29] My approach to JavaScript has been subsetting. [58:32] Any feature which is problematic and that I can live without, I will happily live without [58:36] it. [58:37] It's been said only a madman would use all of C++. [58:40] You could also say only a madman would use C++, but I'm not going to argue that tonight. [58:47] But this approach to subsetting works in every language. [58:50] It's really easy to add features to a language. [58:55] Some designers will think of a clever feature and put it in, and sometimes it works and [58:59] sometimes it doesn't. [59:00] If it doesn't, they cannot take it out. [59:03] If a language is popular, if there is significant use, they cannot remove a bad part without [59:08] breaking things. [59:11] Even if that part is dangerous and causes people to write bad programs, it's stuck there. [59:17] You have a power that language designers and standards bodies do not have -- you can take [59:22] features out of any language at any time by simply refusing to use those features. [59:27] My advice is not that you be ignorant about the features that you don't need -- I think [59:33] it's important that you know the whole language -- but that you know enough to know to avoid [59:38] the features which are working against you and not for you. [59:43] There will be bugs. [59:44] I'm not promising that by using JSLint or using these techniques that you're going to [59:49] be bug free. [59:51] What we're trying to do is to move the odds slightly to your favor. [59:54] Any bugs we can help you to avoid will make you more productive and happier. [59:59] My conclusion: good style is good for your gut, even if your gut doesn't think so. [60:05] Thank you, and good night. [60:15] [applause] [60:19] I think we have time for some questions. [60:20] Do you want to run the mic, or should I repeat? [60:24] OK. [60:25] >> FELIPE GASPER: Has anyone written a JS tidy tool? [60:29] For example, if I write a var statement in the middle of my function, I would love some [60:35] tool that strips out that var and sticks one at the beginning of the function for me so [60:39] I don't have to worry about adding two lines just because I added a new variable to the [60:44] function. [60:45] >> DOUGLAS CROCKFORD: Has anyone written a JS tidy tool? [60:47] >> FELIPE GASPER: Like, Perl has a beautiful one. [60:48] >> DOUGLAS CROCKFORD: Someone may have, I don't know. [60:51] For a long time I've been thinking about writing something called JSMax, which would be the [60:57] reverse of JSMin. [60:58] It would take something and pump it all back up, and it would do things like that. [61:05] But I haven't. [61:07] Maybe somebody else will. [61:08] >> AUDIENCE MEMBER: Do you have any comments on CoffeeScript? [61:11] >> DOUGLAS CROCKFORD: Do I have any comments on CoffeeScript? [61:14] I really like CoffeeScript. [61:15] I think CoffeeScript is a brilliant experiment. [61:20] JavaScript's good parts have nothing to do with its syntax. [61:25] Most of the bad parts in JavaScript are its syntax; it's quite awful. [61:31] CoffeeScript takes the good parts and puts a minimal syntax on top of it, which is lovely. [61:36] I like CoffeeScript a lot. [61:39] I don't recommend using it in production because it comes with its own world of problems and [61:45] I don't think that's a good tradeoff. [61:47] I would like to see JavaScript move in the direction of CoffeeScript in the long run. [61:53] There are a lot of pressures on the language, and I'm not sure it's ever going to get there, [61:56] but that would be my preference if we could. [62:00] Anyone else? [62:03] >> AUDIENCE MEMBER: What are your thoughts on Google Dart? [62:09] >> DOUGLAS CROCKFORD: I'm sorry? [62:11] >> AUDIENCE MEMBER: Google Dart. [62:13] >> DOUGLAS CROCKFORD: Google what? [62:15] Oh, Dart? [62:16] I've thought for a long time if I could take a clean sheet of paper and write a new language [62:24] which corrects every defect in JavaScript but retains all of the goodness in it -- because [62:29] there is a lot of goodness in it -- I would not have come up with anything like Dart. [62:42] That's not to say there aren't some good ideas in Dart, but it doesn't capture the goodness [62:46] of JavaScript. [62:48] It feels like it's trying to go back and be more Java-like. [62:51] And its syntax stinks. [62:56] I don't get it. [62:57] There's something wrong over at Google, I don't know what it is. [63:00] Apparently there are a whole lot of guys over there who think it's a good idea; I don't [63:05] know what's going on. [63:08] >> AUDIENCE MEMBER: Are there any other languages you would borrow any other goodness from to [63:16] add to JavaScript? [63:18] >> DOUGLAS CROCKFORD: I'm not an advocate of trying to make JavaScript bigger. [63:24] I'm actually going the other way, I'd like to make it smaller. [63:30] My goal for the next edition of the standard, which will not be met, but my personal goal [63:34] is to make JSLint unnecessary. [63:37] We're not going to accomplish that. [63:41] Instead we're going to add a lot more stuff which will probably introduce more bad parts [63:44] unintentionally; that's just how this stuff happens if you try to add too much stuff too [63:52] quickly. [63:55] JavaScript sort of miraculously combined functions as first class objects with lexical closures [64:03] and dynamic objects with prototypal inheritance, two things that were never put together, two [64:09] experimental ideas, and put it into the mainstream wrapped in a familiar syntax that worked. [64:17] It's ingenious, and I love that about JavaScript. [64:21] I think that's enough, there's enough there. [64:24] Anything else it needs can be added as libraries. [64:27] >> FELIPE GASPER: You did mention it tonight, but JSLint also has a thing against -- I forgot [64:34] how you put it -- if you use a for in but you don't have a hasOwnProperty check in it. [64:39] >> DOUGLAS CROCKFORD: Yeah, JSLint complains about unfiltered for in statements. [64:43] >> FELIPE GASPER: Doesn't that filtering defeat a lot of the benefits of prototypal inheritance [64:49] though? [64:50] Like, one of my beefs with YUI is that they do this. [64:52] If you have use prototypal inheritance to define your configuration object, YUI will [64:57] reject anything that that configuration object has inherited from the parent object, which [65:04] was really frustrating until I realized that's what was going on, because it seems so counter-intuitive. [65:09] It's this great thing in the language but I can't use it. [65:13] Even Object.keys has this, what seems to me, a flaw. [65:17] >> DOUGLAS CROCKFORD: Well, no, it's not a flaw because it's so hazardous. [65:22] So again, the argument is not that it isn't useful, it's that it's dangerous and error [65:27] prone. [65:28] The reason that I'm recommending you not use it isn't because you can't figure out a clever [65:32] use for it -- I admire you for having found a clever use -- I still recommend you not [65:37] do it. [65:39] >> AUDIENCE MEMBER: Why in the catch statement do you have to use a different variable name? [65:47] >> DOUGLAS CROCKFORD: Why in the catch statement do you have to use a different name in every [65:51] catch? [65:52] It's because in some browsers -- and I don't need to iterate through that list again -- [66:03] all of those become the same variable. [66:08] The correct way to do it should be to make every catch clause, every catch block, be [66:13] a separate scope. [66:16] But in some browsers they don't, so you might think that each one of these is a unique variable, [66:21] and they should be, but they're not. [66:23] If they all have the same name they are all the same variable, and that is a confusion, [66:28] and we don't want to be confused. [66:30] OK, so that's that. [66:31] Thank you very much everybody. [66:33] Be careful going home. [66:34] Good night. [66:35] [applause]