|
| 1 | +# MeTTaScript 2.5.0 |
| 2 | + |
| 3 | +Four engine changes: repeated queries over a knowledge base that has not changed now reuse their |
| 4 | +answers instead of recomputing them, functions that build and test candidate programs compile to |
| 5 | +native code, `superpose` treats a tuple of operators as data the way Hyperon does, and numeric type |
| 6 | +annotations written `Int`, `Integer`, `Double`, or `Float` are accepted as `Number`. The full |
| 7 | +corpus validates byte-identical against 2.4.0; the only outputs that change are the two the new |
| 8 | +semantics exist for, a superposed operator tuple that used to be a type error and now enumerates, |
| 9 | +and an `Int`-style signature that used to reject numbers and now runs. |
| 10 | + |
| 11 | +## Tabling for functions that read a space |
| 12 | + |
| 13 | +Automatic tabling already memoised pure recursive functions. It now also covers a function whose only |
| 14 | +side effect is reading atoms with `match`, which is the shape of a backward chainer: rules stored as |
| 15 | +atoms, a recursive `deduce` that matches them, and the same goal asked many times. The memo key |
| 16 | +carries a whole-world atom-space content version, so a cached answer is reused only while every space |
| 17 | +is unchanged. Any write, `add-atom` and `remove-atom` on `&self` or a named space, `new-space`, |
| 18 | +`fork-space`, `bind!`, an import, or a transaction commit, moves later calls to a fresh key, so a |
| 19 | +query always reflects the current contents. `get-atoms` stays outside the memo because it evaluates |
| 20 | +what it reads. A repeated deduction over a fixed rule base that recomputed every subgoal on every |
| 21 | +query now answers the repeats from the table: a thousand repetitions of a backward-chained goal run about three times faster end to end, with the whole gain on the repeated queries. |
| 22 | + |
| 23 | +## Compiling program synthesis |
| 24 | + |
| 25 | +A generate-and-test program, a non-deterministic generator that builds candidate expressions, a |
| 26 | +checker that evaluates each candidate, and a renderer that prints the winner, previously ran entirely |
| 27 | +in the interpreter. Three additions bring it onto the compiled path. A clause that applies a variable |
| 28 | +bound to a constructor's child, `($op $a $b)` where `$op` came from destructuring, compiles to a |
| 29 | +native numeric dispatch when the value is `+`, `-`, or `*`, and falls back to the interpreter for any |
| 30 | +other head. A single guarded clause that calls another compiled function joins the scalar path, and a |
| 31 | +tail self-call in such a clause loops without consuming an evaluation-depth level, matching the |
| 32 | +interpreter's tail behaviour exactly. The generator's two-clause union and the generate-test-render |
| 33 | +pipeline compile as a unit, preserving clause order, operator order, and the left-to-right product so |
| 34 | +results enumerate in the same sequence as before. Candidate order and multiplicity are unchanged. The depth-2 generate-and-test workload runs about eleven times faster; the depth-1 form about twice as fast. |
| 35 | + |
| 36 | +## Operators as data in superpose |
| 37 | + |
| 38 | +`(superpose (+ - *))` now enumerates the three operators, matching Hyperon. `superpose` splits its |
| 39 | +argument tuple and evaluates each element as a result; a tuple whose head cannot be applied, a set of |
| 40 | +operators carried as data, is the data itself, so the elements are the operators. A tuple that is a |
| 41 | +well-typed call is still evaluated first and its value split, so a computed argument such as |
| 42 | +`(superpose (cdr-atom (collapse (match ...))))` keeps working. The error for a non-expression |
| 43 | +argument now reads exactly as Hyperon's. |
| 44 | + |
| 45 | +## Numeric type aliases |
| 46 | + |
| 47 | +A signature written `(-> Int Int)`, or with `Integer`, `Double`, or `Float`, now type-checks against |
| 48 | +numeric values the same way `Number` does, in both directions: an `Int` parameter accepts any number, |
| 49 | +and an `Int`-typed result satisfies a `Number` parameter such as `+`. The names denote one numeric |
| 50 | +family, so a float is accepted where `Int` is declared. A type you define yourself is unaffected and |
| 51 | +still guards its constructors. `get-type` continues to report the declared name. |
| 52 | + |
1 | 53 | # MeTTaScript 2.4.0 |
2 | 54 |
|
3 | 55 | A native fast path for the functions that destructure data. A deterministic function that matches on its |
|
0 commit comments