agent.md
September 11, 2026 · View on GitHub
Culebra
Source files are .cul. There is no manifest and no package manager;
the whole standard library is in scope without an import.
culebra prog.cul # run (the bytecode VM's executor)
culebra --jit prog.cul # the same output, that bytecode lowered to LLVM
culebra test # run every test_*.cul below the cwd
culebra fmt -i . # format in place (no style options)
culebra lint . # static checks
Look an API up instead of guessing it — especially the ones that
feel too ordinary to check. sort, take, items, length: a name
every language has is where a wrong guess is most confident and least
noticed. The whole reference is inside the binary, so it always
matches the build being run:
culebra docs -g 'Math.wrap' # print the sections that match
culebra docs -g '<name>' >/dev/null # exits 1 when nothing matches
culebra docs stdlib Scene # print one namespace's chapter whole
Exit status is grep's: 0 printed something, 1 nothing matched. A
signature -g cannot find does not exist.
Read culebra docs quick-guide before writing Culebra. It is one
prompt-sized file: the syntax, the signatures a program reaches for
unprompted, and a table of the habits from other languages that do not
carry over. One row of that table, for the kind of thing it covers:
# !! TypeError
'ab' * 3
The quick guide names the stateful subsystems — Scene, Canvas,
Net, PEG, CodeGen and the rest — rather than listing them. Print
the chapter for one before writing against it; its signatures alone do
not say in what order to call them or what owns the result.
Run what you write. Undefined names are rejected before the program
starts, but that check covers names, not members: Math.abss(1) and
xs.len() survive culebra lint and fail when the line runs, and a
missing property is nil rather than an error.