Skip to content

Commit c486e10

Browse files
committed
ziz-drop: Žiz language design, JEG spec, tree-sitter skeleton, Chapel ziz0 bootstrap, and triage of AI-generated material
Staging area for metadatastician/ziz (not yet reachable from this session). Contents: README, DESIGN, docs/JEG, TRIAGE (bins A/B/C of the Gemini transcript), tree-sitter grammar + indent-stack external scanner + corpus, bootstrap/ziz0.chpl (unverified: no chpl available), examples, Justfile fragment. ASCII-only surface; no triads, no dialectics in semantics.
1 parent ebe60f2 commit c486e10

16 files changed

Lines changed: 1632 additions & 0 deletions

File tree

‎ziz-drop/DESIGN.adoc‎

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
// SPDX-License-Identifier: CC-BY-SA-4.0
2+
= Žiz — Design
3+
:toc: macro
4+
:icons: font
5+
6+
toc::[]
7+
8+
Status: *pre-alpha design.* Everything here is intent until `ziz0` runs it.
9+
See link:TRIAGE.adoc[TRIAGE.adoc] for what was deliberately left out, and why.
10+
11+
== One-paragraph summary
12+
13+
Žiz is a unityped, homoiconic, reflexive language. There is one value domain,
14+
programs are values, and the reader, printer, evaluator and environment are
15+
ordinary values reachable from user code. Žiz has *no typechecker* and never
16+
rejects a program for classification reasons. Instead every term carries a
17+
*Judgement Evidence Graph* (JEG) entry: claims about the term, each linked to
18+
the evidence for it (author assertion, static inference, runtime observation,
19+
test outcome). Tooling *reads* the JEG; the runtime *appends* to it. The
20+
first implementation, `ziz0`, is an interpreter written in Chapel.
21+
22+
== What Žiz is *not*
23+
24+
It is not dialectical. Expressions are not triads. There is no boundary
25+
operator, no simplicial complex, no sheaf, no "Real". The name is a pun and
26+
the pun is permitted in documentation and error messages; it has no
27+
semantics. See TRIAGE.adoc §Finding 1.
28+
29+
== Unityped, precisely
30+
31+
Following Harper: a "dynamically typed" language is a statically typed
32+
language with exactly one type. Every Žiz term has type `V`. "Untyped" is
33+
the same fact seen from the syntax side (no annotations, no static
34+
judgement). Runtime tag dispatch is pattern-matching on the single sum
35+
`V = nil + bool + int + real + str + sym + pair + … + (V → V)`. The classical
36+
denotational backdrop is Scott's D∞ (`D ≅ [D → D]`); we cite it and do
37+
nothing further with it.
38+
39+
== Core value domain
40+
41+
[cols="1,2,2", options="header"]
42+
|===
43+
| Tag | Payload | Notes
44+
45+
| `nil` | — | the empty list and the false-ish sentinel
46+
| `bool` | true / false |
47+
| `int` | arbitrary precision | `ziz0` uses Chapel `int(64)` for now
48+
| `real` | IEEE 754 binary64 |
49+
| `str` | UTF-8 byte sequence | *content* may be any Unicode; *syntax* is ASCII
50+
| `sym` | interned name |
51+
| `pair` | car, cdr | lists are right-nested pairs ending in `nil`
52+
| `vec` | contiguous sequence |
53+
| `map` | ordered associative |
54+
| `fn` | params, body, env | closures
55+
| `prim` | host procedure |
56+
| `env` | frame + parent | first-class
57+
| `node` | tree-sitter node id | anchor into the CST; used by the JEG
58+
| `claim` | subject, judgement, evidence | a JEG entry, also a value
59+
|===
60+
61+
== Homoiconicity
62+
63+
Source text →(reader)→ `V` →(evaluator)→ `V` →(printer)→ source text.
64+
The reader's output is the AST; the AST is a list. Macros are ordinary
65+
functions from `V` to `V` marked with `defmacro`.
66+
67+
== Metaiconicity
68+
69+
*Owner's term; this is the working definition pending the owner's own.*
70+
71+
The mapping between text and values is itself a value. Concretely:
72+
73+
* `(reader)` returns the current reader as a `map` of dispatch entries
74+
(`char -> fn`). `(set-reader! m)` installs a new one. Reader macros are
75+
therefore user code, and the *shape* of the language is data.
76+
* `(printer)` / `(set-printer! m)` likewise.
77+
* Both are scoped to the current `env`, so a module can change its own
78+
surface syntax without changing anyone else's.
79+
80+
This is what makes the off-side surface and the plain S-expression surface
81+
*the same language* with two reader tables, rather than two dialects. It is
82+
also where a one-glyph alias for the evaluator (e.g. a Cyrillic letter) would
83+
live *if* the owner wants one: as a reader-table entry mapping to an ASCII
84+
name, never as a lexical primitive.
85+
86+
== Reflexivity
87+
88+
* `(eval v [env])`, `(current-env)`, `(env-parent e)`, `(env-bindings e)`.
89+
* `(jeg)` returns the live Judgement Evidence Graph for the current program.
90+
* `(claim subject judgement . evidence)` appends to it.
91+
* `(node-of v)` returns the CST anchor of a value if it came from source.
92+
93+
Closest existing relative: Kernel (Shutt) — operatives receive unevaluated
94+
operands and the caller's environment as first-class objects. Žiz's
95+
`defmacro` + first-class `env` is a conservative version of that; whether to
96+
go the full fexpr route is an open question.
97+
98+
== Lexical rules (ASCII-only)
99+
100+
The surface syntax uses *only printable ASCII* plus newline and tab.
101+
Identifiers may not contain non-ASCII. String *contents* may. Rationale:
102+
grep/diff/review/terminal/keyboard hygiene, and because anything non-ASCII
103+
that matters can be introduced as a reader alias (§Metaiconicity).
104+
105+
=== `sexp` reader
106+
107+
----
108+
( ) [ ] { } ' ` , ,@ ; <comment to EOL>
109+
"string with \" \\ \n escapes"
110+
integer ::= -?[0-9]+
111+
real ::= -?[0-9]+\.[0-9]+([eE][-+]?[0-9]+)?
112+
symbol ::= [A-Za-z_+\-*/<>=!?%&|^~$][A-Za-z0-9_+\-*/<>=!?%&|^~$.:]*
113+
keyword ::= :symbol
114+
----
115+
116+
`[ ]` reads as a `vec`, `{ }` as a `map`.
117+
118+
=== `layout` reader (off-side)
119+
120+
A line with two or more forms is an implicit list. A following block that is
121+
indented deeper continues that list, one form (or nested implicit list) per
122+
line. A line with a single form is *not* wrapped. `\` at end of line
123+
continues. Explicit brackets disable layout inside them.
124+
125+
Implemented as a tree-sitter *external scanner* emitting
126+
`INDENT` / `DEDENT` / `NEWLINE` from an indent stack — off-side syntax is not
127+
expressible in a context-free grammar, which is why any "N-rule EBNF" claim
128+
for a layout language is wrong on its face.
129+
130+
----
131+
define (fact n)
132+
if (= n 0)
133+
1
134+
* n (fact (- n 1))
135+
----
136+
137+
reads identically to
138+
139+
----
140+
(define (fact n) (if (= n 0) 1 (* n (fact (- n 1)))))
141+
----
142+
143+
== Special forms
144+
145+
`quote` `quasiquote` `unquote` `unquote-splicing` `if` `define` `set!`
146+
`lambda` `defmacro` `begin` `let` `claim`. Everything else is a function.
147+
148+
== Evaluation
149+
150+
Eager, left-to-right, lexically scoped, proper tail calls required of any
151+
conforming implementation (`ziz0` does not have them yet — that fact is a
152+
JEG entry on `ziz0`, not a lie in this document).
153+
154+
Errors are values. A failed operation returns an `error` map and *records a
155+
claim* (`(claim node :raised {...} :evidence :runtime)`). Nothing unwinds
156+
unless the caller asks via `(raise!)`.
157+
158+
== Judgement Evidence Graph
159+
160+
Full model in link:docs/JEG.adoc[docs/JEG.adoc]. Summary:
161+
162+
* *Judgement*: a proposition about a subject (`:callable`, `:arity 2`,
163+
`:returns :int`, `:pure`, `:raised`, `:tested-by`, …). Open vocabulary.
164+
* *Evidence*: why we believe it — *kind* (`:asserted`, `:inferred`,
165+
`:observed`, `:tested`, `:contradicted`) and *provenance* (who/what/when).
166+
* Subjects are CST node ids; the graph survives re-parsing via tree-sitter's
167+
incremental edit tracking.
168+
* Append-only during a run; merged across runs.
169+
170+
A JEG lint reports *unsupported* and *contested* judgements. It never blocks
171+
a build; a `Mustfile` may make a threshold a gate — project policy, not
172+
language semantics.
173+
174+
== Toolchain
175+
176+
Names are the owner's: `claudia`, `boggs`, `federici`, `dunayevskaya`,
177+
`assata`. *Role assignment is undecided.* Two candidate mappings exist
178+
(this repo's original guess, and Gemini's); the owner picks. Needed roles:
179+
180+
. reader/printer registry (metaiconic tables)
181+
. evaluator core
182+
. JEG store / merge / query
183+
. grammar, CST anchoring, editor integration
184+
. CLI / REPL / project driver
185+
. (later) memory / resource management, if not delegated to Chapel
186+
187+
== Bootstrap plan
188+
189+
. `ziz0` (Chapel): `sexp` reader, evaluator, printer, in-memory JEG.
190+
Single locale. No FPGA.
191+
. `ziz0` gains the `layout` reader via the tree-sitter C parser through
192+
Chapel's C interop.
193+
. JEG persisted (`.jeg.a2ml`, see JEG.adoc).
194+
. Self-hosting: reader/evaluator rewritten in Žiz, run under `ziz0`. A
195+
λ-calculus interpreter with the Y combinator is the smoke test.
196+
. Only then: backends. Chapel-PGAS distribution via `chapeliser` first,
197+
because the host is already Chapel. FPGA acceleration lives inside
198+
`chapeliser`, behind Chapel; Žiz never sees it.
199+
200+
== Related work (real)
201+
202+
Kernel (Shutt, fexprs + first-class envs) · Refal (structural rewriting) ·
203+
Scheme R7RS-small (the sexp core) · sweet-expressions / SRFI-110 (layout
204+
over S-expressions) · Harper, PFPL ch. 22 (unityped) · Scott 1969 (D∞).
205+
206+
== Non-goals for the foreseeable future
207+
208+
Static types. A typechecker under another name. Triads. Kaomoji. Bitstreams.

‎ziz-drop/Justfile.ziz-fragment‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# SPDX-License-Identifier: MPL-2.0
2+
# Append these recipes to the Justfile supplied by the RSR template.
3+
4+
build:
5+
chpl --fast bootstrap/ziz0.chpl -o ziz0
6+
7+
examples: build
8+
for f in examples/hello.ziz examples/fact.ziz examples/quote-eval.ziz examples/reflexive.ziz; do \
9+
echo "== $f"; ./ziz0 --file=$f --jeg=observe; done
10+
11+
grammar:
12+
cd grammar && tree-sitter generate && tree-sitter test
13+
14+
ascii-check:
15+
! grep -rnP '[^\x00-\x7F]' examples/ grammar/grammar.js bootstrap/ziz0.chpl | grep -v '"' || true

‎ziz-drop/README.adoc‎

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// SPDX-License-Identifier: CC-BY-SA-4.0
2+
= Žiz
3+
:toc: macro
4+
:icons: font
5+
6+
image:https://img.shields.io/badge/status-pre--alpha-red.svg[Status: pre-alpha]
7+
image:https://img.shields.io/badge/License-MPL--2.0-blue.svg[License: MPL-2.0]
8+
9+
A unityped, homoiconic, *metaiconic*, reflexive language with **no
10+
typechecker** — instead, a *Judgement Evidence Graph* records what is
11+
believed about every term and why. Bootstrapped in Chapel.
12+
13+
toc::[]
14+
15+
== Status — read this first
16+
17+
*Nothing runs yet.* This repository holds a design, a tree-sitter grammar
18+
skeleton, and a Chapel bootstrap interpreter that has not yet been through a
19+
Chapel compiler. If a model or a person tells you Žiz is "locked in", is
20+
"dialectical", evaluates "triads", or can be "synthesised end-to-end in 48
21+
hours", see link:TRIAGE.adoc[TRIAGE.adoc].
22+
23+
== Routing
24+
25+
[cols="2,3", options="header"]
26+
|===
27+
| If you want… | Go to
28+
29+
| What Žiz is, precisely, and what it is not
30+
| link:DESIGN.adoc[DESIGN.adoc]
31+
32+
| The Judgement Evidence Graph — the thing that replaces a typechecker
33+
| link:docs/JEG.adoc[docs/JEG.adoc]
34+
35+
| Which AI-generated claims about Žiz are real, misapplied, or invented
36+
| link:TRIAGE.adoc[TRIAGE.adoc]
37+
38+
| The grammar (tree-sitter, ASCII-only, off-side via external scanner)
39+
| link:grammar/grammar.js[grammar/grammar.js], link:grammar/src/scanner.c[grammar/src/scanner.c]
40+
41+
| The bootstrap interpreter
42+
| link:bootstrap/ziz0.chpl[bootstrap/ziz0.chpl]
43+
44+
| Examples
45+
| link:examples/[examples/]
46+
|===
47+
48+
== Sixty-second tour
49+
50+
[source,lisp]
51+
----
52+
(define (fact n)
53+
(if (= n 0) 1 (* n (fact (- n 1)))))
54+
55+
(claim fact :arity 1 :evidence :asserted) ; a judgement, with provenance
56+
(print (fact 10))
57+
----
58+
59+
----
60+
$ ziz0 --file=examples/fact.ziz --jeg=observe
61+
3628800
62+
; --- JEG: 6 judgements, 23 evidence edges
63+
(sym:fact :arity 1) ; asserted=1 observed=11
64+
(sym:fact :takes 0 :int) ; observed=11
65+
(sym:fact :returns :int) ; observed=11
66+
(sym:fact :pure) ; asserted=1
67+
----
68+
69+
No type was declared. No type was checked. Every belief about `fact` is in
70+
the graph with the evidence that supports it; tools decide what to do with
71+
that, and they can disagree with each other.
72+
73+
== Building (once Chapel is available)
74+
75+
----
76+
just build # chpl --fast bootstrap/ziz0.chpl -o ziz0
77+
just examples # runs every examples/*.ziz the sexp reader can read
78+
just grammar # tree-sitter generate && tree-sitter test
79+
----
80+
81+
== Toolchain names
82+
83+
`claudia` · `boggs` · `federici` · `dunayevskaya` · `assata` — the owner's
84+
names. Role assignment is *not yet decided*; see TRIAGE.adoc appendix.
85+
86+
== Governance
87+
88+
Follows the Rhodium Standard Repository conventions from
89+
`hyperpolymath/standards` (the RSR template supplies `SECURITY`,
90+
`CONTRIBUTING`, `Mustfile`, `.machine_readable/`, etc.). Language policy:
91+
Chapel for the bootstrap, C only for the tree-sitter scanner, JavaScript
92+
only for the tree-sitter grammar DSL. No Python, no Rust component, no Deno.

0 commit comments

Comments
 (0)