The Hara language course
This course continues from Read Hara and build from scratch. It takes the same small reading model from ordinary values into the runtime boundaries used by complete programs.
No previous Clojure knowledge is assumed. You will work with the actual Hara language and libraries rather than a reduced teaching dialect.
What you will learn
Section titled “What you will learn”The course develops seven connected parts of Hara:
- Basic data types and persistent collections.
- Functions and atoms.
- Sequences, iterators, and streaming.
- Coroutines and promises.
- Explicitly mutable arrays and objects.
- Bytes and strings.
- Capability-gated I/O and files.
The order matters. Each lesson uses the values and boundaries introduced by the earlier lessons.
Why these boundaries matter
Section titled “Why these boundaries matter”Hara’s simplicity comes from keeping a small set of distinctions visible as the program grows:
| Ordinary model | Explicit boundary |
|---|---|
| persistent vectors, maps, sets, and lists | mutable array and object values |
| plain immutable value | atom for current changing state |
lazy, replayable Seq | one-shot iterator |
| immediate result | promise that settles later |
| normal function call | resumable coroutine |
| string | mutable bytes |
| pure transformation | host capability and I/O |
The course does not hide these distinctions behind a framework. It teaches you to recognise and use each one deliberately.
The course project
Section titled “The course project”You will build a small line-processing program.
The final program will:
- Represent configuration with persistent maps and vectors.
- Use functions to transform records.
- Store live progress in an atom.
- Stream records through sequences and iterators.
- Coordinate work with coroutines and promises.
- Use arrays and objects at explicit mutable boundaries.
- Encode and decode text as bytes.
- Read and write files through granted capabilities.
The project is intentionally compact. The goal is to expose the runtime model clearly enough that you can transfer it to a browser application, command-line tool, service, or embedded host.
How to use each lesson
Section titled “How to use each lesson”Keep a Hara REPL or the browser Playground open while you read.
For each example, use the same loop:
- Predict the result before running the form.
- Run it in the live session.
- Change one value or operation.
- Inspect the returned value.
- Explain the new result in one sentence.
This turns syntax into an observable rule and keeps the running system close to the source.
Stable vocabulary
Section titled “Stable vocabulary”The course uses one term for each concept:
- A value is data that an expression returns.
- A form is Hara data that the evaluator can run.
- A persistent collection is an immutable collection that returns updated values.
- A function receives values and returns a value.
- An atom stores one replaceable value.
- A Seq is Hara’s lazy, replayable sequence boundary.
- An iterator is a one-shot source of values.
- A promise represents a value that can settle later.
- A coroutine is a resumable computation.
- An array or object is an explicitly mutable marker value.
- Bytes are mutable binary storage.
- I/O is an effect that crosses from Hara into its host environment.
A new name appears only when the course introduces a new runtime concept.
Course map
Section titled “Course map”01 — Basic data and persistent collections
Section titled “01 — Basic data and persistent collections”Read numbers, booleans, strings, keywords, symbols, lists, vectors, maps, and sets. Update persistent collections without mutation.
Define transformations with fn and defn. Use an atom when a running program needs one replaceable value.
Build lazy pipelines. Distinguish reusable values, lazy Seq values, and one-shot iterators.
Represent deferred results with promises. Suspend and resume control flow with coroutines.
Use explicit mutable markers at host, protocol, and performance boundaries. Keep them separate from persistent collections.
Transform text with string functions. Encode and decode UTF-8. Inspect and update byte buffers.
Resolve paths safely. Read and write bytes through promises. Understand capability grants and effect boundaries.
After the course
Section titled “After the course”Continue according to what you want to build:
- Build Tic Tac Toe for a complete visual browser program.
- Namespaces, libraries, and tests for larger source trees.
- Namespace project walkthrough for a multi-file service shape.
- Choose your Hara setup for the CLI, web, JVM, VS Code, or Emacs.
- L0 language contract for exact semantics.
- Runtime library contract for intrinsic namespaces.
Start with 01 — Basic data and persistent collections.