Lesson 00 · DeepSeek Harness and Cordis

Values, Types, and Function Calls

The zero-prerequisite foundation for the entire formal course

Start here

This course is self-contained. You do not need to read the Cordis paper or know type theory. We will build the vocabulary from ordinary examples before introducing Greek letters.

Your tangible win

After this lesson, you will be able to look at a compact formal statement and separate four different things:

Description
effect : State → (State, Undo)
Actual value
effect
Actual run
effect(empty)
Actual result
(has_model, remove_model)

Most of the confusion in formal papers comes from accidentally treating a description of a value as if it were the value being executed. This lesson prevents that mistake.

1. Values are the things in memory

A value is a concrete thing a program can hold or use.

42 "hello" true {} {"model", "tools"} remove_model

All of those are values. A function is also a value. The function named remove_model is not the same thing as running it.

For this running example, let a State be a set of capability names:

empty = {} has_model = {"model"} remove_model(s) = s \ {"model"}

Because remove_model removes the model key from {"model"}, we can verify:

remove_model({"model"}) = {}
Function value
remove_model

The reusable operation itself.

Function call
remove_model(state)

Running the operation on one state.

Compare the difference:

remove_model remove_model({"model"})

The first line refers to a function. The second line runs the function on one concrete state and, in our example, produces {}.

2. Types describe allowed values

A type is a description of what kind of value something is allowed to be. It is not one concrete value.

Type
Number

Describes numeric values.

Value
42

One particular number.

Type
State

Describes possible runtime states.

Value
empty

One particular state.

This is why a type signature does not show one current state:

abs : Number → Number

This does not mean that abs is currently receiving a number. It says that whenever we give abs a number, it returns a number.

abs(-9) = 9

The 9 appears only in the actual call, not in the general type description.

The key distinction

Type: what shape a value has. Value: one concrete thing. Call: running a function on a value.

3. Function types

The arrow symbol describes a function type:

A → B

Read it as:

A function that accepts an A and returns a B.

Examples:

Number → Number String → Boolean State → State

The last one describes a state transformation:

add_model : State → State add_model(s) = s ∪ {"model"} add_model(empty) = has_model

The type tells us the input and output categories. The call tells us what happened for one particular input.

What do X and x mean?

Formal writing often uses uppercase letters for types and lowercase letters for values:

X = the type of possible inputs x : X = one actual input Y = the type of possible outputs y : Y = one actual output f : X → Y f(x) = y

So x is not a special kind of thing. It is just a placeholder name, like empty or 9. In the Cordis paper, a generic line such as f_impure : X → Y means: the function accepts some ordinary input x : X and returns some result y : Y. Later, when context is made explicit, the same idea can be written:

f : Γ × X → Γ × Y f(γ, x) = (δ, y)

That says the function receives both the current context γ and the ordinary input x, then returns a new context δ and an ordinary result y.

4. A pair is two values bundled together

A pair, also called a product, is a value containing two values:

(first, second) ("model", 200) (has_model, remove_model)

The pair type can be written with the product constructor:

A × B

A pair value is written with concrete values:

(a, b) (has_model, remove_model)

Some informal writing uses (A, B) as shorthand for the pair type, but keep the levels separate: uppercase A and B name types, while lowercase a and b name values.

Here × does not mean multiplication. It means "a pair of an A and a B."

For example, the pair type (State, Undo) has:

First component
State

The new context state.

Second component
Undo

The function that can undo the change.

5. Functions can return pairs

Put the previous two ideas together. First, name the type of an undo function:

Undo = State → State

An undo function is just a state-transforming function that we intend to use for recovery; the type alone does not prove that it really undoes anything.

effect : State → (State, Undo)

This says:

  1. effect is a function.
  2. It accepts one State.
  3. It returns one pair.
  4. The pair contains a new State and an Undo function.

Now make it concrete:

effect : State → (State, Undo) effect(empty) = (has_model, remove_model) remove_model(has_model) = empty

That is the complete idea before any Greek notation appears.

Important: the arrow does not mean undo

Γ → Γ only says "a function that takes one context state and returns another." It does not automatically mean undo.

add_model : State → State remove_model : State → State

Both functions have the same type. We call remove_model an undo function only because we separately require the relationship for the states where the model was not already present:

remove_model(add_model(state)) = state provided "model" ∉ state

The type tells us the shape. The equation, together with its precondition, tells us the behavior.

6. Now translate into the paper's symbols

Only now do we introduce the paper's names:

State = Γ one state = γ new state = δ Undo = Γ → Γ Effect = EΓ effect = e

Our plain-English type:

effect : State → (State, Undo)

becomes:

EΓ = Γ → (Γ × (Γ → Γ))

Notice the direction of the explanation: the formal line does not turn into a different type. We first choose an input and run the function:

e : Γ → (Γ × (Γ → Γ)) x : Γ e(x) = (new_state, inverse_function)

After that run, we can name the two returned values. Their types are:

new_state : Γ inverse_function : Γ → Γ

So (new_state, inverse_function) is the result of a call, not a replacement for the type-level pair Γ × (Γ → Γ).

And our concrete call:

effect(empty) = (has_model, remove_model)

becomes:

e(γ) = (δ, g)

The symbols are not introducing a new operation. They are short names for the same ordinary idea:

Plain EnglishFormal symbol
Possible state spaceΓ
One current stateγ
One resulting stateδ
Effect functione
Undo functiong
Type of effects over ΓEΓ

7. What the course will do next

Lesson 01 combines contexts, inverse effects, accumulators, and dependency predicates. Later lessons add the unified context, lifecycle calculus, asynchronous transitions, and system-wide theorems.

Course dependency order: plain programming idea, then values, types, functions, calls, pairs, then Cordis notation, then the runtime model built from contexts, effects, dependencies, and components
Figure 1: The dependency order. Each layer is taught before the next one uses it. [D2 source]

Retrieval checkpoint

Try to answer before revealing the models.

1. Is effect a type, a value, or a function call?

2. Is effect(empty) a type description or an actual run?

3. What does (State, Undo) mean?

4. Translate e(γ) = (δ, g) into English.