- 1. Overview
- 2. Lesson Structure
- 3. Lessons
- 3.1. Lesson 1: Unicode & Smart Quotes (E0007)
- 3.2. Lesson 2: Unterminated Strings (E0002)
- 3.3. Lesson 3: Missing Blocks (E0005)
- 3.4. Lesson 4: Unexpected Tokens (E0001)
- 3.5. Lesson 5: Invalid Escape Sequences (E0003)
- 3.6. Lesson 6: Illegal Characters (E0004)
- 3.7. Lesson 7: Unmatched Parentheses (E0006)
- 3.8. Lesson 8: Identifier Rules (E0008)
- 3.9. Lesson 9: Reserved Keywords (E0009)
- 3.10. Lesson 10: Error Recovery (Advanced)
- 3.11. Lesson 11: Structured Loss (Echo)
- 4. Assessment Ideas
- 5. Teacher Guide
- 6. Appendix: Error Code Quick Reference
Error-Lang turns the compiler toolchain into the curriculum. Each lesson corresponds to an error code, teaching students how compilers work by forcing them to diagnose and fix intentionally injected errors.
Each lesson follows this format:
-
Concept Introduction - What the error teaches
-
Example Code - Program with gutter block
-
Error Encounter - Run until error is injected
-
Diagnosis - Use
error-lang explainto understand -
Fix - Apply the correction
-
Verification - Run again to confirm
Concept: Character encoding and text editor settings
The Problem:
Many text editors and word processors automatically convert straight quotes
(“) into "smart" or "curly" quotes (” and "). Programming languages
almost universally require straight quotes.
Example:
main
gutter
let greeting = "Hello, World!" # Wrong!
end
endLearning Objectives:
-
Understand ASCII vs Unicode
-
Configure text editor for programming
-
Recognize invisible character issues
Concept: String literal boundaries
The Problem: Forgetting to close a string with a matching quote.
Example:
main
gutter
let message = "This string never ends
let next = "This won't work either
end
endLearning Objectives:
-
Understand lexer state machines
-
Recognize multi-line string issues
-
Learn about escape sequences for newlines
Concept: Block structure and nesting
The Problem:
Forgetting to close a block with end.
Example:
main
if true
println("Inside if")
# Missing 'end' for if!
gutter
while true
println("Forever")
# Missing 'end' for while!
end
endLearning Objectives:
-
Understand block-structured languages
-
Count opening/closing delimiters
-
Use indentation as visual aid
Concept: Parser expectations
The Problem: The parser expected one kind of token but found another.
Example:
main
gutter
let = 42 # Missing identifier
let x y = 10 # Missing =
println "hello" # Missing parentheses
end
endLearning Objectives:
-
Understand grammar rules
-
Read error messages for context
-
Learn operator/operand relationships
Concept: String escape processing
The Problem: Using an unrecognized escape sequence in a string.
Example:
main
gutter
let path = "C:\new\folder" # \n and \f are escapes!
let regex = "\d+\s*" # \d and \s aren't valid
end
endLearning Objectives:
-
Know valid escape sequences:
\n,\r,\t,\\,\" -
Understand when to escape backslashes
-
Learn raw string alternatives (future lesson)
Concept: Valid character sets
The Problem: Using characters that aren’t part of the language syntax.
Example:
main
gutter
let price = $100 # $ isn't valid
let emoji = 🎉 # Emoji in identifiers
let math = α + β # Greek letters
end
endLearning Objectives:
-
Understand lexer character classes
-
ASCII vs extended characters
-
Language design choices
Concept: Expression nesting
The Problem: Parentheses, brackets, or braces don’t match up.
Example:
main
gutter
let x = ((1 + 2) * 3 # Missing )
let arr = [1, 2, 3 # Missing ]
let fn = fn(x -> x # Missing )
end
endLearning Objectives:
-
Count delimiters carefully
-
Use editor matching features
-
Understand stack-based parsing
Concept: Naming conventions
The Problem: Identifiers must follow specific rules.
Example:
main
gutter
let 123abc = 1 # Can't start with number
let my-var = 2 # Hyphen not allowed
let my var = 3 # Space not allowed
end
endLearning Objectives:
-
Valid identifier patterns
-
Case sensitivity
-
Naming conventions (snake_case, camelCase)
Concept: Language reserved words
The Problem: Using a keyword as a variable name.
Example:
main
gutter
let if = 10 # 'if' is reserved
let end = 20 # 'end' is reserved
let function = 30 # 'function' is reserved
end
endLearning Objectives:
-
Know the keyword list
-
Understand why keywords are reserved
-
Choose appropriate names
Concept: How compilers keep going after errors
The Problem: Understanding parser recovery strategies.
Example:
main
println("Before error")
gutter
let x = @#$%^& # Totally broken
let y = "unterminated
println(
end
println("After error - still runs!")
endLearning Objectives:
-
Synchronization points
-
Error cascades
-
Panic mode recovery
Concept: Decomposition made visible — loss can be structured, but it is never free or hidden
The Problem:
Most languages discard information silently. Error-Lang makes the moment of loss
observable: an Echo<A, B> holds a witness and its output; echo_to_residue
erases the witness into an EchoR<A, B>, debiting the Stability Score.
Example:
main
let e = echo(42, "answer") # Echo<Int, String>
println(echo_input(e)) # 42 — witness still here
println(echo_output(e)) # "answer"
let r = echo_to_residue(e) # erasure — stability drops here
println(echo_output(r)) # "answer" survives
println(residue_strictly_loses(r)) # true — loss is observable
gutter
println(echo_input(r)) # ERROR: the witness is gone
end
endLearning Objectives:
-
Structured loss vs. silent discard
-
Irreversibility:
EchoRnever coerces back toEcho -
Consequence amplification: the erasure stability debit is visible, charged once
-
The invariant decomposition must be visible
-
Given this error message, what’s wrong with the code?
-
Fix this program to eliminate the error
-
Predict what error this code will produce
-
Explain why this character isn’t allowed
-
Run a program 10 times, document all unique errors
-
Create a program that triggers a specific error
-
Modify the gutter to be "more broken" in different ways
-
Explain to a partner what each error teaches
-
Install Deno on all machines
-
Clone the Error-Lang repository
-
Run
error-lang doctorto verify setup -
Distribute example files
-
Introduce the error code and concept (5 min)
-
Demonstrate the error occurring (5 min)
-
Students explore with their own variations (15 min)
-
Discuss findings as a class (10 min)
-
Document learnings in notes (5 min)
| Code | Name | One-line Fix |
|---|---|---|
E0001 |
Unexpected token |
Check grammar and syntax |
E0002 |
Unterminated string |
Add closing quote |
E0003 |
Invalid escape |
Use valid escape or \\ |
E0004 |
Illegal character |
Remove or replace character |
E0005 |
Missing 'end' |
Add end to close block |
E0006 |
Unmatched paren |
Balance () [] {} |
E0007 |
Smart quote |
Use straight quotes |
E0008 |
Bad identifier |
Follow naming rules |
E0009 |
Reserved keyword |
Choose different name |
E0010 |
Whitespace issue |
Check indentation |