aboutsummaryrefslogtreecommitdiffstats
path: root/docs/design/001-language-v0.md
Commit message (Collapse)AuthorAgeFilesLines
* Give a view a body that computes and returns its value (Pure 018)eunhhu2026-10-041-2/+2
|
* Count with for i in a .. b, break, nest fors and let an event's own lists ↵eunhhu2026-10-041-3/+3
| | | | (Pure 018)
* Declare transient state: held while the app runs, never stored (Pure 018)eunhhu2026-10-041-2/+2
|
* Say what library records showed (002)eunhhu2026-10-041-1/+1
| | | | | | | The task list's module is the same with its record in a library (2,509 bytes); one record of a library's three goes into a module using one; a migration of the same library moves what the app stored; eleven diagnostics. The example compiles.
* Give aup an i64: exact integers, and literals typed by what they meeteunhhu2026-09-301-2/+30
| | | | | | | | | | | | | | state, record, message, output and argument fields, lets, views, keys and slices can be i64 (Pure 016 stage 2). An integer literal becomes an i64 where the other side of an operation, a comparison or an assignment is one; a literal-only side follows the other, found by compiling it on trial and rolling back. + - * and negation fail the event with overflow, / and % floor, and i64(x) and number(n) are the only way between the two, so a mix is a diagnostic that says so. The check adds 18 i64 diagnostics, i64 accepted forms (with a 30-deep chain that must stay linear), an event-by-event program past 2^53 and at the edges, and i64 values in the generated programs.
* Give aup a bool: true and false, and conditions that take oneeunhhu2026-09-301-6/+31
| | | | | | | | | | | | | | | | | | | | | | | A condition was any number, non-zero being true: done was a number field, a view showed 1 for true, and done + 1 was no type error. Now bool is its own type (Pure 016, module format v6): - true and false; comparisons, text comparisons, has and ! && || give a bool. Bools are equal or not; they are no numbers and have no order. - if, conditional expressions, require, where (folds, walks, filtered tables) take a bool. Given a number, the diagnostic says how to make one: "if takes a bool, not a number: compare it, as in n != 0". - Bool states (state on = false), record fields (done = false), message, output and argument fields (ok: bool), lets, views and columns. Interpolation writes true or false. A list is not keyed by a bool. - The examples' flags are bools (charge's holding, toggle's visible, tasks' done). Checks: 20 bool diagnostics, a form using bools everywhere, an app whose every output shows true and false (states, items, views, columns, text) and whose replacement turns a number into a bool and back. Models hold bools and compare them strictly: Python's True == 1 no longer hides a 1 where a true belongs. Generated programs are typed, numbers and bools.
* Let declared fields be apart by commas, as a value's areeunhhu2026-09-301-0/+1
| | | | | | | | | | A message's, a group's and a record's fields took a newline or a semicolon after each, while a value's (Kept { id: 1, t: "a" }, send) take commas, and the language's own examples declared message { title: text, points: number } and to: { city: text, zip: u32 }, which did not compile. Now a comma, a newline or a semicolon ends a declared field too (one after the last as well); without one it says so.
* Write a message once for its output and the input that takes iteunhhu2026-09-301-0/+4
| | | | | | | | | | | | Growing a board two nodes share (Pure's research 105), one field took five places, two of them the same list: the output a node sends its changes on and the input it takes the other's with. A message may now take the fields of a message input or output declared before, in their order: input remote = message like changed. The module is the same as with the fields written out, byte for byte (checked). An unknown name, one that is no message, the message itself, and an output taking an input's rows are diagnosed.
* Check a payments API's answers coming back as events exactly onceeunhhu2026-09-271-0/+3
| | | | | | | | | A Python payments API answers 200 or 402 and repeats a key's first answer; the sender's output is wired to it and its answers to the charged input. With the sender killed (-9) while clients buy, the app's paid and declined counts and paid total match the API's answers one per key. The language notes say how answers arrive.
* Declare outputs and send them: output ordered = message { ... }eunhhu2026-09-271-0/+4
| | | | | | | | | | | An output is a message the app sends, with fields and groups as a message has; send ordered { item: x, to: { city: y } } gives every field once, in any order, groups in their own braces, and compiles to Pure's SEND. Diagnostics cover a missing field, a group given a value, an unknown field, a mistyped value, a send to a message, a handler for an output, a field given twice and reading an output as a state; kinds in messages now carry their article (an output, a key input).
* Group message fields: to: { city: text }, read as ship.to.cityeunhhu2026-09-271-0/+4
| | | | | | | | | | | | | | | | | | A message's field block may hold groups, nested as deep as the 31 characters of a path allow; the compiler flattens them into fields named by their path (to.city), which Pure's module format takes, so groups cost nothing at run time. A member chain on a message names a field by its path; one that stops at a group, or names a field the group lacks, is diagnosed, and a field's own member (m.text.bytes) still reads the field. A module may have 64 message fields. The JSON server check posts 100 random bodies with groups two deep (members shuffled at every level, strings with escapes, control bytes, Korean, emoji and U+2028) to pure-serve, which reads them in place, and compares the answers and the table with a Python model; a group's fixed field from the query and ten malformed group bodies are checked too. Six diagnostics cover groups.
* Declare number and text message fields; check JSON bodieseunhhu2026-09-261-1/+4
| | | | | | | | | input add = message { title: text, points: number } now compiles, with variable fields anywhere and several of them. The served-app checks post 300 random JSON objects (escapes, control bytes, Korean, surrogate pairs, members in any order) and read them back as Python's json module does, with a list of bodies that must be refused and why.
* Check declared state across restartseunhhu2026-09-251-0/+4
| | | | | | | | The list app and the text editor run on a tree store through pure-run --store, restarting at random points, and must keep matching their reference models. The language notes state that a declared state is a stored state when the host gives a store.
* Add fns and librarieseunhhu2026-09-251-3/+4
| | | | | | | | | | | | | | | | fn name(params) = value declares one expression, inlined where it is called: arguments are computed once onto the stack and the body reads them with PICK, so a fn costs no runtime call and keeps Pure's bound on work. Parameters take any kind of value; recursion is a compile error. use name reads name.aup beside the source or from AUP_PATH. A library declares only fns and uses, sees only its parameters, and is called as name.fn(...). Diagnostics now carry the file they are in, and the compiler takes a loader so that sources come from the host. examples/words.aup is such a library; examples/tasks.aup uses it and still matches its reference model.
* Add conditional expressions and table viewseunhhu2026-09-251-2/+2
| | | | | | | | | | | | | | | | | if c { a } else { b }, with else-if chains, is an expression anywhere a value goes. Only the chosen branch runs, every branch gives the same type, and nesting that would pass Pure's limit of 8 value-carrying joins is a compile error. view name = each row in list { column = value ... } declares a table with a row per item; columns read their row as an index of the list. An index now reads and writes its item's fields directly (at.title, at.done = 1), so 'position' cannot name a record field. examples/tasks.aup gains conditional views and a board table and still matches its reference model; a new check confirms the unchosen branch is never computed.
* Emit Pure module format v5eunhhu2026-09-251-1/+1
| | | | | | | Pure now loads only v5 modules, where a view entry's type is one byte followed by the table it belongs to. Plain views encode as before, so the output changes only in its magic. The view limit follows Pure's to 64.
* Record the input limit of 32 in the language noteseunhhu2026-09-251-1/+1
|
* Add records, lists and indiceseunhhu2026-09-251-2/+3
| | | | | | | | | | | | | | A record declares named number and text fields with defaults. A list of a record is runtime-owned state, and an index of a list always names one of its items: it follows its item across inserts and removes and stops at the ends. Items are read and changed by field (tasks[at].title), appended or inserted as record values whose missing fields take defaults, and removed by index. Using an index of another list is a compile error. examples/tasks.aup matches a Python reference model over 4,800 random steps, including events that fail on an empty list. Replacing it with a module whose record gained and reordered fields keeps every item.
* Document the text language as implementedeunhhu2026-09-251-1/+1
| | | | | | | Record v0b as complete: which text syntax exists, what is still missing (multi-line strings, formats, graphemes, words), the insertion rule for cursors, and how the text model and parity checks verify it.
* Compile messages and keyed documents to module v2eunhhu2026-09-251-16/+23
| | | | | | | | | | | | | | | | | | aup now emits Pure module v2 and adds keyed byte collections (state documents: bytes by key), message inputs by key with u32 and a trailing bytes field, on-message handlers, field access, name[key] reads and .bytes sizes, replace(a .. b, value), reply and require, all checked for number/bytes types with file:line:column diagnostics. The document editor and its size-bounded variant are rewritten in aup. make check runs them through pure-edit-module against pure-edit running the original editor.pure programs: 1,280 random show/edit/apply operations, including conflicts, limits, missing documents, budgets and invalid keys, produce byte-identical stdout, stderr and exit codes, and each CLI reads the other's store identically. v0a parity with the workbench engine, 33 diagnostics and generated/damaged programs still pass, also with a sanitizer-built compiler.
* Charter aup and specify language v0eunhhu2026-09-251-0/+110
aup is the language and toolchain for the Pure runtime, as Java and javac are for the JVM. v0a unifies the workbench scalar dialect (state, key inputs, atomic handlers, views) with the same numeric semantics; v0b drafts byte values and runtime-owned persistent documents to replace the document dialect. Parity with the existing executors is the acceptance test.