-
tklips v0.5.1 Stable
released this
2026-11-06 10:48:34 +00:00 | 0 commits to master since this releasetklips v0.5.1: rule priorities, the standard library of releases at the repository's new location, and error lines after the output they follow. The reference PDF documents the language as released.
Breaking changes
- The releases' standard library moved with the repository, from
experiments/tklipstotklips/tklips-lang.(std name version)giveshttps://code.thunderk.net/tklips/tklips-lang/raw/tag/<version>/stdlib/<name>.tk, which serves every release, the earlier ones included. Only that location is trusted: a library URL written out under the formerexperiments/tklips/raw/tag/prefix is an ordinary URL now, which needs--allow-url,allowUrlorallow_url. Write(std name version)instead, or the new URL.
Rules
(*priority* n)among a rule's conditions orders it among the rules that no*after*or*before*declaration relates to it: higher priorities first,0by default, then definition order.*after*and*before*always take precedence. A library's end-of-turn rule can take(*priority* -1000)to come after the rules of the modules that require it.nis an integer as written; errors:rule: missing priority <d>,rule: invalid priority <v>,rule: duplicate marker *priority*andrule: misplaced marker *priority*.
Command line
- With stdout and stderr sent to the same place, a form's error line now comes after what the form wrote before the error. It came first when stdout was a pipe.
SHA-256
fc2953e24c3fb440c62f52bb34b9e594354176361c38be69ea9d58b443b747b9 tklips-v0.5.1-linux-x86_64 5fa690e585611bfdaa23317fa36f5ff4d2fb1cea027a87e8cd9f0eabec7ed850 tklips-v0.5.1.mjs 55f7dc0e8dc2e61052fc34ee105a7df88e45b4f0f877c12a8a242fb4801612cb tklips-v0.5.1.py a4924c4705fafffe7b5866d7d752e8292814532782ff3afa859032bdf25fb429 tklips-v0.5.1-reference.pdfDownloads
- The releases' standard library moved with the repository, from
-
tklips v0.5.0 Stable
released this
2026-11-05 21:40:57 +00:00 | 5 commits to master since this releasetklips v0.5.0: files and streams, constants, help in the shell, random draws, and aggregates in rules, which also check much less work again after a change. The reference PDF documents the language as released.
Breaking changes
piandeare removed. Write the constants&PIand&Einstead of(pi)and(e).setreturns the value it binds,_included, instead of_. The shell and batch mode write that value as the result of a top-levelset;(and (set o x) ...)goes on whenxis true; andsetas a fact predicate keeps the facts whose value is true. Where a program relied on the_, write(block (set x v) _).- Global variables cannot take a constant's name.
(set PI 3)at top level fails withset: cannot shadow constant PI, and so do the other built-in constants:TAU,E,INT-MAX,INT-MIN,STDIN,STDOUTandSTDERR. Rename such variables; parameters and variables inside functions and rules may still use these names.
Language
- Constants.
(const NAME value)defines a constant at top level, with an upper-case name; it cannot be defined again.&NAMEreads it everywhere, in function bodies, lambdas and rules included, unless a parameter or local variable shadows it.(const-list)lists them all. The built-in constants arePI,TAU,E,INT-MAX,INT-MIN,STDIN,STDOUTandSTDERR. The new error codes aredefine/constantanddefine/scope. - Help.
(? name)writes a function's signature and what it does, and where a user function was defined. It evaluates none of its arguments, so?can head a call being written:(? text-pad-left 42 5).(?)lists every function and constant.(func-info f)gives the same as an object. The#lines right above a top-levelfuncorconstare its doc, and every built-in and standard library function has one. - Files, URLs and standard streams.
(io-open path fn (.mode read))opens a resource, callsfnwith its integer id, and closes the resource howeverfnends, errors and interrupts included.(io-with (in a.txt) (out b.txt (.mode write)) body...)does the same around a body.io-read-line,io-read,io-writeandio-printread and write a resource.io-infoandio-listinspect the open ones.- Ids
0,1and2are stdin, stdout and stderr. Files are opened inside the current directory, with moderead,writeorappend. URLs are read only. - Errors belong to the new
io/family:io/denied,io/not-found,io/not-accessible,io/closed,io/mode,io/readandio/write.
- Random draws.
(random),(random end)and(random start end)draw a float in [0, 1), or a number in [start, end), an integer unless a bound is a float.(shuffle obj)gives the items of an object in a random order.(seed n)replays the draws of a seed,(seed)sets a fresh one and returns it, and(seed-get)gives the seed in effect.- With
.key, a draw is fixed by its key and the seed, and leaves the generator as it was. - The generators are xoshiro256** and SipHash-1-3, so a seed gives the same draws on every host. They are not cryptographic.
- Standard library, new libraries:
file:file-read,file-write,file-appendandfile-each-line.enum:enum,enum-str,enum-name,enum-hasandenum-check, which builds and checks sets of named constants.random:random-pickandrandom-sample.
Facts
fact,fact-find,fact-find-readandfact-del-allfind facts by their first written value through an index, instead of walking the whole relation.
Rules
- Aggregates.
(*collect* (name expr) c...)always holds. It bindsnameto an object holding the values ofexpr, one for each way facts satisfyc..., or to(obj)when none do. The rule fires again when that object changes, so a rule with afactupsert keeps an aggregate fact up to date:(fact total (.order &o) > (.sum (+ *prices))). A name already visible fails withrule: already captured <name>. - Chance.
(*chance* p key...)holds with probabilityp, drawn with a key made of the rule's name and the keys, or every visible capture when no key is written. A new seed draws every condition again. Unkeyedrandomandshuffle, andseed, fail in rule conditions withnot allowed in a rule condition, as the fact andio-built-ins do. - Faster checks.
runandrun-preparelook at a fired activation or a tracked support again only when a change concerns it. A rule whose relations did not change costs nothing.rule-statscounts these looks as(.checked n).
Interactive shell
- A top-level
setwrites the value it binds (see Breaking changes).
Command line
--seed <n>starts random draws from the seedn. Without an integer after it, it fails withtklips: --seed needs an integer.- When the program comes from a file, stdin is the stream
0that programs read.
JavaScript module
- The
open(path, mode)option opens resources forio-open, and thestdin(max)option gives what stream0reads. The defaults:- Node opens files inside the current directory, fetches URLs with
allowUrl, and reads its standard input. - A browser fetches every path, relative to the page.
- Node opens files inside the current directory, fetches URLs with
- What a program writes to stream
2goes to thestderroption. - The
seedoption starts random draws from a seed, andresetgoes back to it. resetforgets the program's constants.
Python module
- The
open,stdinandseedoptions, as in the JavaScript module. Stream2goes tostderr, andresetforgets the program's constants. - Evaluations nested 100 deep through Python functions fail with
stack overflow, as in the JavaScript module; they could fail withthe engine failedinstead.
SHA-256
5675c463b1b5f767d792533c3db1cbd98b674ce30e55ca0d812851a5f3ebe443 tklips-v0.5.0-linux-x86_64 0b61bee6a797a3bf86f5376cd6db9093cfdf0d9d0e056e53f5e49bbbdb03beec tklips-v0.5.0.mjs 4113a781321a5c3dec57a91e1db2ddcdf256160c951a55278141cd4b8495560c tklips-v0.5.0.py 112d0534cb72828fcb478660a9acaf5da8d56afb144dfc96d8daf483e6dd85fc tklips-v0.5.0-reference.pdfDownloads
-
tklips v0.4.1 Stable
released this
2026-10-27 20:16:36 +00:00 | 14 commits to master since this releasetklips v0.4.1: fixes to the codes and display of errors raised by JavaScript and Python functions. The language is unchanged otherwise, and the reference PDF is v0.4.0's, which documents it, except for the display described below.
Breaking changes
- An error with a code of its own from a JavaScript or Python function displays its code. An error that
tklipsFail("not-found", "no user")orfail("not-found", "no user")raises in a functionlookupnow displays asnot-found: lookup: no user, in the shell's error line and in theTklipsError's message, as every error with a code that is not built-in does; it displayed aslookup: no userbefore, and asnot-found: lookup: no useronly once a program raised it again with(fail &e). The error object's.messageis stilllookup: no user. Code that compares the message of such aTklipsErrorshould expect the code first, or compare itscodeand.messageinstead.
Language
js/errorandpy/errorare built-in error codes, the codes of errors in JavaScript and Python functions that give none of their own: an error with either displays its message alone, also raised again with(fail &e). A Python function's error raised again displayed aspy/error: <name>: <message>before.
Python module
- A Python function whose result has no tklips form, or that returns an awaitable in a synchronous
Runtime, fails with the codepy/error; it wasjs/error.
SHA-256
b19d321b364178612e71618daf5fa3bc7f002b5f9985b4258efa0add4a70e137 tklips-v0.4.1-linux-x86_64 d20ec86769ab8ef1b97e5a84057116cd9659624ffd66dc2983958c4692ad7618 tklips-v0.4.1.mjs 8e8b4b39802041770ca0c08f4d44a76fe9298f091431da45abc732514de5c6bf tklips-v0.4.1.py 8e1ce33859fee37252c55a4d075b31f17e27112a55a16be34b9be5b72e6ec95b tklips-v0.4.1-reference.pdfDownloads
- An error with a code of its own from a JavaScript or Python function displays its code. An error that
-
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
-
tklips v0.3.0 Stable
released this
2026-10-23 16:50:32 +00:00 | 28 commits to master since this releasetklips v0.3.0 splits programs into sources with a standard library, handles errors as values, names built-in arguments, and gives rules test conditions and simpler patterns; the JavaScript module becomes asynchronous.
tklips-v0.3.0-reference.pdfdocuments the language as released.Breaking changes
- Capture patterns (
fact-match,fact-match-read, rule patterns) capture into bare names: write(person name (.age a))instead of(person &name (.age &a))..agealone is short for(.age age). - No literals in capture patterns: write
(person .sex (= &sex M))instead of(person (.sex M)). A number in a pattern now fails withinvalid variable name, and a text is a capture, so an old pattern with text literals matches more facts. - Strict functions: a user function or lambda without a rest parameter rejects arguments it has no parameter for, with
<f>: expected at most <n> arguments, got <m>and<f>: unknown named argument <name>. Add a rest parameter (*rest) to accept them. - New built-in names:
require,std,fail,try,catchandrecovery. A function of one of these names must be renamed. - Error messages and output: built-ins with parameter names report
<f>: missing argument <param>and<f>: expected at most <n> arguments, where they reportedexpected <n> arguments; an error raised inside a function is followed by its trace lines; the shadowing warning writescapture a shadows a variable, without&. - JavaScript API:
eval,call,apply,run,runProgram, and a session'sfeedandendreturn Promises:awaitthem.define,undefine,resetandsession()stay synchronous.
Language
(require source)imports a source once, in the scope where it is written, running its forms without echo; errors in it are located aslib.tk:2:1.- The standard library, written in tklips:
(require (std text))imports thetextlibrary, withtext-pad-left,text-pad-right,text-center,text-lines,text-wrap,text-capfirstandtext-capwords.(std text v0.3.0)names the copy of a given release. - Errors are values with a code (
type/not-text,unknown/function,arg/arity…), a message, data and a trace:(fail code message (.name value)…)raises one, its named arguments as data, and(fail e)raises a caught one again;(try expr… (catch e handler…) (catch (e code…) handler…))handles them, a code ending with/taking a whole family;(recovery value)in ablock, atryor a rule's actions ends the rest of the body withvalue, or a function's result on the error, when an error comes after it.
- An error nothing handles is written with the calls it went through:
in f, called at 3:1. - Built-ins take their arguments by position or by name:
(str-sub s (.end 3)),(reduce xs &+ (.init 10)),(partial map (.fn f)),(range 10 (.step 3)),(run (.limit 5)), and likewisestr-find,str-replace,str-repeat,slice,chunk,repeat,sort,filter,count,any,all,find,find-pos,group-by,partition,for-each,logandatan.str-subandslicestart at 0 by default.
Rules
(*test* expr…)holds when its expressions are true, with the captures of the conditions before it: to compare patterns,(rule bigger (p x) (q y) (*test* (> &x &y)) > …), as an alternative of*either*, or as what every match of*every*satisfies. It can be*persist*or*track*.- An error in a rule's test or action can be handled by
recoveryin its actions, which ends that firing and letsrungo on, or by atryaroundrun.
Command line
tklips main.tkruns a program file instead of stdin;tklips -i main.tkruns it, then opens the shell.--allow-urlletsrequirefetchhttp://andhttps://sources withcurl; files are read only inside the current directory.--stdlib <location>takes the standard library from another directory or URL; a release reads its own tagged copy by default.
JavaScript module
- A JavaScript function may return a Promise: the evaluation waits for it where the call stands, and the function may call back into its runtime meanwhile.
createRuntime({ resolve, read, stdlib })says whererequirefinds sources and where the standard library is; by default, paths are URLs, and Node reads files of the current directory.TklipsErrorhascode,data,traceandsource;tklipsFail(code, message, data)makes an error a JavaScript function can throw with a code.
SHA-256
0462340c083f37e115d12f74f00f7926468cafad99ad16a7adc6f48590a34249 tklips-v0.3.0-linux-x86_64 b9b12f85d113c9640f1bb6adf7a2caa17d91648c991ad3ce4dd695d925ae4674 tklips-v0.3.0.mjs 8da22559b355325af6ab84af4d20726346f51feb3b1845b275ec229a29068f15 tklips-v0.3.0-reference.pdfDownloads
- Capture patterns (
-
tklips v0.2.1 Stable
released this
2026-10-22 20:32:56 +00:00 | 36 commits to master since this releasetklips v0.2.1 makes the engine faster and the Linux binary five times smaller, with the same language as v0.2.0. The attached reference PDF, unchanged from v0.2.0, documents the language as released.
Language
- Programs run about twice as fast, more on code that calls many functions:
(fib 25)takes less than half the time it did, and so dosortwith a comparator,mapandfilterwith a function. - Calling a function that has a rest parameter, such as
(func g *r &r), no longer leaks a value now and then:(mem)reports a steadylivecount over repeated calls.
Command line
- The Linux binary weighs 256 KB instead of 1.3 MB. It is still a single static executable with no dependency, now built against musl instead of glibc.
JavaScript module
- The module gets the same speedup, about 2.5 times faster on call-heavy programs.
SHA-256
e2dea262399acec6cfe64bf9c957b6c7250e3dea785b8724545685a30b1c7137 tklips-v0.2.1-linux-x86_64 e295b218c4d92ac45a89c57366da84303b52d4ea6e60e96adb4c180f73722429 tklips-v0.2.1.mjs d184f6030d5fbcb2b480dd61f492fa75ccbbb5a73230a93cef8309b152c9fb68 tklips-v0.2.1-reference.pdfDownloads
- Programs run about twice as fast, more on code that calls many functions:
-
tklips v0.2.0 Stable
released this
2026-10-22 19:24:05 +00:00 | 39 commits to master since this releasetklips v0.2.0 grows the language with text, number and collection built-ins, gives rules an explicit firing order and fact tracking, and ships the engine as a JavaScript module. The language reference for this version is attached as a PDF.
Breaking changes
%is nowrem, with the same behavior:(% 7 3)becomes(rem 7 3). The newmodis the floored modulo, with the sign of the divisor.attrsreturns an object's attributes as an object,(obj (.x 1)), instead of a list of(obj (.name x) (.value 1)). Usekeyvaluesfor a list of(obj name value)pairs, andkeysorvaluesfor the names or values alone.fact-setandfact-updateare removed, and so is the keyed form offact-add((fact-add rel key... > update...)). Write(fact-change id update...)for(fact-set id > ...)and(fact-update id > ...), and(fact rel pattern... > update...)for(fact-set rel pattern... > ...).- A call whose head is
&namenow calls whatnameholds:(&f 1)used to fail withunknown function: &f. - Many new built-in names (listed below) can no longer be defined with
func. A&namereference to one of them where no variable of that name is visible, such as&lastor&min, now gives the built-in's function value instead of failing withunbound variable. Variables of those names keep working where they are visible.
Language
- Texts:
str-len,str-sub,str-find,str-starts,str-ends,str-split(at a separator, into characters or at whitespace, with.max),str-join,str-upper,str-lower,str-trim,str-ltrim,str-rtrim,str-replace,str-repeat,str<,str>,str<=,str>=andstr-cmp. They take texts only and count characters, not bytes.strturns any value into a text, andnumreads a number back, giving_when the text isn't one. - Kinds:
kindnames any value's kind (int,float,str,none,list,obj,func), andis-int,is-float,is-number,is-str,is-none,is-list,is-objandis-functest for one. - Numbers:
floor,ceil,roundandtruncreturn integers;abs,min,max,mod,cmp;pow, exact on integers;sqrt,exp,log(with an optional base),sin,cos,tan,asin,acos,atan(with atan2),(pi)and(e). A result that isn't a real number fails withnot a real number.nearscompares two numbers to 10 decimal places, or.digits. - Collections, on an object's items, keeping their positions:
filter(without a predicate, it removes the holes),reverse,slice,concat,flatten,partition,zip,chunkandnumbered. Giving new lists:sort(stable, with a comparator or a.key),unique,group-by,range(integers or floats, with.inclusive) andrepeat. Giving one value:reduce,find,find-pos,any,all,count,firstandlast. - Attributes:
keys,values,keyvalues,from-keyvaluesandmerge.itemsandattrssplit an object in two, and(obj *i *a)rebuilds it. (. obj key...)follows a path of keys, giving_as soon as an entry is missing or a value on the way isn't an object.- Functions:
call,map,compose,pipeandpartial. Wherever a function is expected, its name works too, and(&f args...)calls the function a variable holds. pprintwrites a value in an indented form, one entry per line.
Facts
fact-addalways adds a fact.fact-changechanges the fact with a given id.factis the upsert by pattern: with> update...it updates the one match or adds the pattern and updates it; without, it adds the pattern only when nothing matches, and returns the id either way.
Rules
(*after* name...)and(*before* name...), written among a rule's conditions, put it after or before other rules whenever both have activations pending.*track*on a condition, or(*track*)for every condition of a rule, makes a firing own the facts it creates: once a tracked condition stops holding, the nextrunremoves them, as CLIPS does withlogical.
Interactive shell
- A result holding nested objects prints one entry per line, indented. Batch mode keeps every result on one line.
JavaScript module
- New:
tklips-v0.2.0.mjs, one ES module with the engine compiled to WebAssembly, for Node 18+ and browsers.createRuntime()gives independent runtimes witheval,call,apply,run,reset,runProgramand interactivesessions. Values convert both ways, and errors throw aTklipsError. definemakes JavaScript functions callable from tklips as built-ins, with named arguments if asked for;undefineremoves one.
SHA-256
4e4619692df2f7ff1fcfaffacde23a17ce8a1f18e05c96804139ce22423a305d tklips-v0.2.0-linux-x86_64 d184f6030d5fbcb2b480dd61f492fa75ccbbb5a73230a93cef8309b152c9fb68 tklips-v0.2.0-reference.pdf 97140e6b455dcf98538394a72ef68c95a271ac30a8604f3e44b675ab1082fe57 tklips-v0.2.0.mjsDownloads
-
tklips v0.1.0 Stable
released this
2026-10-20 07:32:46 +00:00 | 16 commits to master since this releaseFirst release of tklips, a CLIPS-inspired rule language, as a single statically linked binary for Linux x86_64. Run a program with
./tklips < program, or start the interactive shell with./tklips(or./tklips -ion piped input).Language
- S-expression reader with texts, numbers, lists and objects; results are echoed in a canonical form.
- Comments:
#to the end of the line, and(# ...)forms. - Function calls with positional and named arguments (
(.name value)), including names and positions taken from variables ((.&var value)). - Variables with
set,getand&name. Scopes are globals, function bodies and rules. - User functions with
funcandlambda: default arguments, rest parameters (*rest) and spreads (*var). Functions are values, usable withfor-each. - Control flow:
if,while,block,and,or,not, equality and numeric comparisons. Every non-empty text is true, and truth results are1and0. - Arithmetic with
+ - * / %on integers and floats, with errors on division by zero and overflow. - Objects:
obj, lookup,put,delete,push,pop,insert,remove,len,attrs. - Output and text:
print,join. - Values are shared with copy-on-write;
memcounts allocated and live values.
Facts
- A fact store: each fact is a relation and an object body, with an implicit
.id. fact-add(optionally with a key, to add only when nothing matches),fact-set(an upsert by id or pattern),fact-update,fact-get,fact-del,fact-del-all.- Queries with
fact-find,fact-matchand their-readvariants. Patterns match literals, capture slots with&name, filter with inline predicates and join on shared captures.
Rules
ruleandrun. A rule fires once per combination of matching facts, and again when a captured value changes or its conditions stop holding and hold again.- Conditions:
*none*,*some*,*every*and*either*. A condition marked*persist*never makes the rule fire again when it stops holding and holds again. - A rule's predicates and actions only see their own captures, not the caller's or global variables.
Interactive shell
- A REPL with
tklips>and...>prompts, line editing and history. It keeps going after errors; Ctrl-C drops the current form and Ctrl-D ends the session.
SHA-256
4dccb6077b6e822f9d1d323b9e4918da3f3943ff9e65f1fbca78140ae48aaa1a tklips-v0.1.0-linux-x86_64Downloads