Eulisp Documentation

*
[2026-02-16 Mon]

1. Eulisp,

Eulisp is a small, expression-based language where programs describe effects as data, and the runtime (Ω) decides how and when to execute them safely.

Programs do not “do things” directly. They declare effects. Execution authority lives outside the language.

2. What Is Eulisp?

Eulisp is built around three core ideas:

  • Effects are data
  • Control flow is forbidden inside effect declarations
  • All execution authority lives outside the language

You construct a dependency graph of effect descriptions. Ω (the Governor) later admits, orders, executes, and records them.

3. Who This Is For

This guide is for:

  • complete beginners (including people who have never programmed)
  • people who want practical copy-paste examples
  • contributors who want a quick mental model before reading dev docs

For runtime internals, see docs/dev-docs.org.

4. Start Here (No Prior Programming Needed)

4.1. Key Idea 1: Everything Is an Expression

In Eulisp, everything is an expression. An expression produces a value.

42
"hello"
(add 2 3)

4.2. Key Idea 2: Effects Are Data First

When you write:

(print "hello")

It does not immediately print.

It creates an EffectDescription. Ω executes it later.

5. Execution Model

An eulisp program goes through four stages:

  • Parsing Source code → S-expressions.
  • Elaboration Syntax → AST. Ethical and structural constraints are enforced here.
  • Evaluation (Pure) Expressions evaluate. Effects are collected, not executed.
  • Governance & Execution Governor decides:
    • which effects are admissible
    • when they can run
    • whether dependencies are satisfied

Then it executes them and records them in a ledger.

5.1. Multi-Pass Execution

Execution proceeds in dependency-aware passes:

  • Effects with satisfied dependencies are ready.
  • Ready effects execute (or reuse cached results).
  • Successful IDs and results are stored.
  • Dependents of changed results are marked dirty.
  • If no progress can be made, remaining effects are rejected.
  • Stop at fixpoint (or max pass limit).
  • Execution is deterministic and idempotent.

6. Your First Program

(effect main ()
(print "Hello from Eulisp"))

What happens:

  • main describes one print effect.
  • Governor executes it.
  • You see output.

7. Language Concepts

7.1. Literals

42
"hello"

7.2. Variables

x

7.3. Let Bindings

(let (x 10)
(add x 5))

7.4. Conditionals

(if (gt x 0)
(print "positive")
(print "non-positive"))

7.5. Sequences

(seq
expr1
expr2
expr3)

7.6. Lambdas

(lambda (x y)
(add x y))

Pure vs Effect Functions

Functions are defined at the top level using pure or effect.

7.7. Pure Functions

May compute values but must not directly emit effects.

(pure add-two (x)
(add x 2))

7.8. Effect Functions

Must contain exactly one expression. That expression must not contain control flow.

(effect say-hi (name)
(print name))

Inside an effect function body, do not use:

  • if
  • let
  • seq
  • nested function definitions

This keeps effect descriptions non-decisional and auditable.

8. Effects As Values

Effects are created using primitives like:

(print "hello")
(write-file "out.txt" "data")
(read-file "out.txt")
(done "finished")
(sleep 1000)

These do not perform IO immediately. They return structured values of type EffectDescription. Effects may be:

  • stored
  • returned
  • composed
  • placed in lists

At the end of evaluation, all effects reachable from main are collected.

9. Useful Effect Primitives

; file artifact with optional dependencies
(emit-artifact "artifact.txt" "content")
(emit-artifact "artifact.txt" "content" (list dep-id))

; read realized result of an effect
(result some-effect)

A Practical File Example

(effect main ()
((lambda (template templateRead0)
((lambda (templateRead)
(list
template
templateRead
(emit-artifact
"todo-today.txt"
(concat
"# Daily Checklist\n\n"
(result templateRead)
"\nGenerated by eulisp.\n")
(list (hash templateRead)))
(done "demo complete")))
(depend (hash template) templateRead0)))
(emit-artifact
"todo-template.txt"
"- [ ] Review priorities\n- [ ] Ship one thing\n")
(read-file "todo-template.txt")))

10. Dependencies

Dependencies are explicit and manual.

(depend
(hash first-effect)
second-effect)

Meaning second-effect may run only after first-effect succeeds. Multiple dependencies:

(depend (list h1 h2 h3) effect)

10.1. Chain (Simple Linear Sequence)

(chain
(print "a")
(print "b")
(print "c"))

Each effect depends on the previous one.

11. Lists and Higher-Order Construction

You can declaratively build effect graphs:

(let (effects
(map sleep (list 100 200 300)))
(depend
(map hash effects)
(print "all done")))

No loops. No runtime branching. Just graph construction.

12. Data Primitives

12.1. Concat

Strings:

(concat "hello" " " "world")

Lists:

(concat (list 1 2) (list 3 4))

12.2. String Escapes

\n newline

\t tab

\r carriage return

\ backslash

" quote

Example:

(print "line1\nline2")

13. Effect Identity

Every effect has a cryptographic identity: SHA256(canonical encoding of EffectDescription)

(hash (print "hello"))

Properties:

  • identical descriptions → identical IDs
  • IDs are 256-bit SHA digests
  • identity is content-addressed
  • no counters
  • no runtime integers
  • runtime result does not affect identity

14. Governor

Ω is not part of the language syntax. It is the runtime authority.

Responsibilities:

  • admit or reject effects
  • enforce idempotence (via SHA256 identity)
  • resolve dependencies
  • execute effects in parallel waves
  • record an immutable ledger
  • verify outcomes
  • detect cycles and unresolved deadlocks
  • pre-validate dependency graph

The ledger is:

  • append-only
  • deterministic (sorted by EffectID)
  • persisted in sqlite

Each entry stores:

  • pass number
  • decision
  • outcome
  • structured result

15. Structured Logging

Runtime logs are structured.

Modes:

  • default → pretty structured logs
  • --json-logs → JSON log lines
  • --silent → hide system logs (user print and done still visible)

Example JSON log:

{"timestamp":"...","level":"info","event":"effect.print","message":"hello"}

16. CLI Flags

Common flags:

  • --ledger
  • --print-ledger
  • --clear-ledger
  • --debug
  • --print-graph
  • --json-logs
  • --silent

17. Tiny Copy-Paste Examples

17.1. Minimal Hello

(effect main ()
(print "hello"))

17.2. Parallel Sleeps Then Final Message

(effect main ()
((lambda (sleeps)
(list
sleeps
(depend (map hash sleeps)
(print "all tasks complete"))))
(map (lambda (id) (sleep id 500))
(list "a" "b" "c"))))

17.3. Write → Read → Print

(effect main ()
((lambda (w r0)
((lambda (r)
(list
w
r
(depend (hash r)
(print (result r)))))
(depend (hash w) r0)))
(write-file "x.txt" "hello from file")
(read-file "x.txt")))

Plan / Status

17.4. DONE Replace stringly-typed effect args

17.5. DONE Structured SHA256 IDs

17.6. DONE Persist ledger in sqlite

17.7. DONE Strong dependency validation (cycle detection + DAG visualization)

17.8. DONE Structured logging modes

17.9. TODO Make Ω restartable

18. Elsewhere

18.1. References

18.2. In my garden

Notes that link to this note (AKA backlinks).

Recent changes. Attachment Index Tag Index Bibliography Index Source.