-
tklips v0.4.0 Stable
released this
2026-10-25 22:58:17 +00:00 | 16 commits to master since this releasetklips 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(coderule/condition): everyfact-built-in,run,run-prepare,rule-agendaandrule. 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 withrule: 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 afile:one withrequire: URLs need allowUrl, as the binary needs--allow-url. PasscreateRuntime({ allowUrl: true })to fetch them. In a browser, URLs stay allowed unlessallowUrlisfalse. - 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.mdis now an ordinary source, which needs--allow-url(orallowUrl) like any other URL.(require (std name))is unaffected.
Language
- Interrupts. Ctrl-C, or
rt.interrupt(), makes the evaluation fail at its next step withinterrupted, codesystem/interrupt; a second one during an interrupted evaluation givesaborted, codesystem/abort. Acatchtakes asystem/error only when it names its code orsystem/, so a barecatchorrecoverynever swallows one; nothing catchessystem/abort. - Stack limit. An evaluation holds at most 200000 calls of functions, lambdas and
runwaiting for their result: one more fails with<name>: stack overflow, codelimit/stack, whichtryhandles 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-agendalists the pending activations in firing order, changing nothing;rule-firedthe activations each rule remembers having fired;rule-ownedthe facts tracked firings own;(rule-firing), in actions, the activation being fired;rule-statsper-rule counters (fired,tried,evaluated);(run-prepare)does whatrundoes 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>, codeunknown/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.runProgramreturns 130 when asystem/error ended it.- A
TklipsErrorthat 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
allowUrloption (see Breaking changes).
Python module
- New:
tklips-v0.4.0.py, one Python file with the engine inside, for Python 3.10+ withpip install wasmtime(Linux, macOS and Windows). It has the JavaScript module's API in Python form:Runtime, whose methods run to their end, andAsyncRuntime, whose evaluating methods are coroutines and whose Python functions may beasync. - Values: integers, floats, texts and
Nonefor_convert as themselves; every tklips object is aTklipsObject, adictwithintkeys for positions andstrkeys for names, whoseto_list()gives the positions' values. Named arguments cross as keyword arguments both ways:rt.call("str-sub", "hello", end=2), anddefine(..., named=True)passes them as**kwargs. - Errors raise a
TklipsError; a Python function's exception becomes<name>: <message>, codepy/errorunless it has acode, asfail(code, message, **data)gives it.rt.interrupt()works from any thread, and Ctrl-C during an evaluation of aRuntimeis an interrupt, raised, if nothing catches it, as aTklipsInterrupt, also aKeyboardInterrupt. URLs are required only withallow_url=True. - Run as a script,
python tklips-v0.4.0.pybehaves 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 codejs/errorinstead ofpy/error; andpy/erroris not yet a built-in code, so a caught Python error raised again with(fail &e)displays aspy/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.pdfDownloads
- 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