• v0.4.0 2e3f9a5e88

    tklips v0.4.0 Stable

    michael released this 2026-10-25 22:58:17 +00:00 | 16 commits to master since this release

    tklips v0.4.0: interrupts and a stack limit, rule introspection, faster rules, and a new Python module beside the binary and the JavaScript module. The reference PDF documents the language as released.

    Breaking changes

    • Rule conditions are pure. In a rule's predicates and tests, and in the functions they call, the built-ins that read or change facts or rules fail with <name>: not allowed in a rule condition (code rule/condition): every fact- built-in, run, run-prepare, rule-agenda and rule. Write a condition on other facts as a pattern or a marked condition instead, such as (*none* (q)) in place of (*test* (= (fact-find q) (obj))). How often predicates and tests run is now unspecified, since their results may be reused while the facts they captured from are unchanged.
    • *persist* and *track* on a test fail with rule: misplaced marker <m>: they could change nothing. Drop the marker.
    • JavaScript module in Node: URLs need allowUrl: true. The default resolution refuses a URL other than a file: one with require: URLs need allowUrl, as the binary needs --allow-url. Pass createRuntime({ allowUrl: true }) to fetch them. In a browser, URLs stay allowed unless allowUrl is false.
    • Stdlib trust. A source is trusted as part of the standard library only when what follows the stdlib directory is a plain relative path: non-empty segments, none . or .., with no % and no \. An escaped path such as …/stdlib/%2e%2e/README.md is now an ordinary source, which needs --allow-url (or allowUrl) like any other URL. (require (std name)) is unaffected.

    Language

    • Interrupts. Ctrl-C, or rt.interrupt(), makes the evaluation fail at its next step with interrupted, code system/interrupt; a second one during an interrupted evaluation gives aborted, code system/abort. A catch takes a system/ error only when it names its code or system/, so a bare catch or recovery never swallows one; nothing catches system/abort.
    • Stack limit. An evaluation holds at most 200000 calls of functions, lambdas and run waiting for their result: one more fails with <name>: stack overflow, code limit/stack, which try handles like any other error.
    • Faster calls: a call resolves its function and checks its arguments once per call site, and a function's body finds its variables by slot.
    • Function and rule definitions that are replaced are released once nothing runs them any more.

    Rules

    • Introspection. rule-agenda lists the pending activations in firing order, changing nothing; rule-fired the activations each rule remembers having fired; rule-owned the facts tracked firings own; (rule-firing), in actions, the activation being fired; rule-stats per-rule counters (fired, tried, evaluated); (run-prepare) does what run does before choosing and says what it did. The first three take rule names and a .limit. An undefined rule name fails with <name>: unknown rule <v>, code unknown/rule.
    • Faster matching. Facts are indexed by relation and by joined value, and each rule keeps its pending activations, brought up to date from the facts changed since: a rule nothing changed for tries nothing. Which activations fire, and in which order, is unchanged.

    Interactive shell

    • Ctrl-C interrupts the form being evaluated, and the session goes on with the state it left.

    Command line

    • In batch mode, a system/ error that nothing handles ends the program, with exit status 130.
    • A URL's dot segments written with escaped dots (%2e) are removed like . and .., as browsers and the JavaScript module do.

    JavaScript module

    • rt.interrupt() interrupts every evaluation of the runtime, including one waiting for a JavaScript function's Promise, whose result is then ignored; evaluations let the event loop run every few tens of milliseconds. runProgram returns 130 when a system/ error ended it.
    • A TklipsError that a JavaScript function throws is raised again unchanged, with its code, message, data and trace, as (fail e) raises an error object.
    • Through JavaScript functions that call back into their runtime, evaluations nest at most 100 deep: one more fails with stack overflow.
    • The allowUrl option (see Breaking changes).

    Python module

    • New: tklips-v0.4.0.py, one Python file with the engine inside, for Python 3.10+ with pip install wasmtime (Linux, macOS and Windows). It has the JavaScript module's API in Python form: Runtime, whose methods run to their end, and AsyncRuntime, whose evaluating methods are coroutines and whose Python functions may be async.
    • Values: integers, floats, texts and None for _ convert as themselves; every tklips object is a TklipsObject, a dict with int keys for positions and str keys for names, whose to_list() gives the positions' values. Named arguments cross as keyword arguments both ways: rt.call("str-sub", "hello", end=2), and define(..., named=True) passes them as **kwargs.
    • Errors raise a TklipsError; a Python function's exception becomes <name>: <message>, code py/error unless it has a code, as fail(code, message, **data) gives it. rt.interrupt() works from any thread, and Ctrl-C during an evaluation of a Runtime is an interrupt, raised, if nothing catches it, as a TklipsInterrupt, also a KeyboardInterrupt. URLs are required only with allow_url=True.
    • Run as a script, python tklips-v0.4.0.py behaves as the binary does.

    Known issues

    • Python module: a Python function whose result has no tklips form, or that returns an awaitable in a synchronous Runtime, fails with the code js/error instead of py/error; and py/error is not yet a built-in code, so a caught Python error raised again with (fail &e) displays as py/error: <message>. Both will be fixed in the next release.

    SHA-256

    620a52797cd4be42914e260b30fdd2179f89fe35a27212079bc898712dd5b436  tklips-v0.4.0-linux-x86_64
    100f5ce7bc7e232ab8feb4514df67ab8b0dfb4f8cad0b881473a602a301dbc15  tklips-v0.4.0.mjs
    4dabfba44259b8230446c16855f36fde7be3cd71cc6dfac6878b22b5abf0da8b  tklips-v0.4.0.py
    8e1ce33859fee37252c55a4d075b31f17e27112a55a16be34b9be5b72e6ec95b  tklips-v0.4.0-reference.pdf
    
    Downloads