Date: 2026-07-06
Companion doc: BEGINNER_GLOSSARY.md.
Hum should let a person who knows English but not programming describe useful software, then guide them into precise code.
The goal is not to let vague English execute. The goal is to make the first programming concepts feel like ordinary reasoning:
- what exists
- what should happen
- what the task uses
- what the task changes
- what must be true first
- what must be true after
- what can go wrong
- what edge cases matter
Beginners do not struggle because programming lacks English words.
They struggle because most languages introduce too many hidden concepts at once:
- state
- mutation
- types
- scope
- control flow
- null
- errors
- files
- dependencies
- naming
- side effects
- testing
Hum should reveal those concepts in the order a human naturally asks questions.
Hum tools should be able to ask:
- What are you trying to make?
- What things exist in the program?
- What should the program remember?
- What actions can happen?
- What does each action use?
- What does each action change?
- What must be true before each action?
- What must be true after each action?
- What can go wrong?
- What edge cases worry you?
Those answers become Hum blocks.
Beginner word: thing.
Hum word: type.
type Task {
title: Text
done: Bool
}
Beginner word: remember.
Hum word: store.
store tasks: list Task {
why:
remember the user's tasks
}
Beginner word: action.
Hum word: task.
task add task(title: Text) -> Result Task, TaskError {
why:
let the user remember something to do
changes:
tasks
needs:
title is not empty
ensures:
new task is saved
new task is not done
does:
create task with title
save task in tasks
return task
}
Beginner word: if.
Hum word: if.
if task is done {
show completed style
} else {
show active style
}
Beginner word: for each.
Hum word: for each.
for each task in tasks {
show task
}
Beginner word: what can go wrong.
Hum word: fails when and fail.
fails when:
title is empty
does:
if title is empty {
fail TaskError.empty_title
}
Beginner word: check.
Hum word: test.
test add task rejects empty title {
does:
expect add task("") fails with TaskError.empty_title
}
Beginner words: how much work.
Hum word: cost.
cost:
time: O(tasks)
space: O(1)
allocates: nothing
Beginner words: do not do it that way.
Hum word: avoids.
avoids:
saving empty titles
network call inside loop
The first human-facing standard library should include:
- show text
- ask for text
- ask yes/no
- read a file
- save a file
- list items
- filter items
- sort items
- find first item
- count items
- current time
- random safe token
- simple HTTP request
- simple JSON read/write
These are not necessarily primitive compiler features. They are the first teaching surface.
When a beginner writes:
does:
save task in tasks
but forgot:
changes:
tasks
the compiler should not say only:
error: undeclared mutation
It should say:
error: this task changes `tasks`, but `tasks` is not listed under `changes:`
why:
Hum makes mutation visible so readers know what this task can modify.
fix:
add `tasks` under `changes:` or stop saving to `tasks`.
Beginner diagnostics should teach the mental model.
Hum should support an agent workflow:
hum new
hum ask
hum draft
hum explain
hum check
hum tests
Flow:
- Human describes the program in ordinary language.
- Agent drafts Hum source.
- Compiler rejects vague or unsafe parts.
- Agent repairs using machine diagnostics.
- Human reads the final source as promises.
The compiler remains the authority.
- Do not execute arbitrary English.
- Do not hide types forever.
- Do not hide errors.
- Do not hide mutation.
- Do not call generated code correct because an agent wrote it.
- Do not teach beginners habits that fail in systems code.
Build a tiny task list before a web server.
It teaches:
typestoretaskwhychangesneedsensuresfails whenfor eachif
Then build the session-store demo to show Hum can scale from beginner clarity to security-sensitive systems thinking.