16 special forms and 154 functions — the language core, the prelude written in EELisp itself, the database, and the agenda.
Evaluated by the interpreter itself, so they don't follow the usual argument rules.
| Form | Meaning |
|---|---|
(def name value) | define a global binding |
(defn name (params) body…) | define a function |
(fn (params) body…)(lambda (params) body…) | an anonymous function |
(let (a 1 b 2) body…) | local bindings, given as one flat list |
(set! name value) | reassign an existing binding |
(if test then else) | two-way branch |
(cond test result …) | flat multi-way branch |
(and a b …) · (or a b …) | short-circuiting logic |
(begin e…) | evaluate in order, return the last |
(for-each var list body…) | loop over a list |
(loop (a 0 b 1) body…) | tail-recursive loop with bindings |
(recur v…) | jump back to the enclosing loop |
(quote x) · 'x | don't evaluate |
(quasiquote x) · ` , ,@ | template, unquote, unquote-splicing |
(defmacro name (params) body…) | define a macro; rest parameters allowed |
A parameter list may end with . rest to collect the remaining arguments.
| Function | Notes |
|---|---|
+ - * / | variadic arithmetic |
mod | remainder |
abs · min · max | |
floor · ceil · round | |
pow | (pow base exp) |
= · != | equality |
< · > · <= · >= | ordering |
not | logical negation |
| Function | Notes |
|---|---|
(str a b …) | concatenate anything, converting as needed |
(str-len s) | |
(str-upper s) · (str-lower s) | |
(str-trim s) | |
(str-split s sep) | → a list |
(str-join sep parts) | accepts either argument order |
(str-contains s needle) | |
(str-matches s pattern) | regular expression test |
(str-replace s target repl) | replaces every occurrence |
(substr s start end) | |
(str-starts-with s p) · (str-ends-with s p) |
| Function | Notes |
|---|---|
(list a b …) | |
(cons x lst) | prepend |
(head lst) · (car lst) | first element |
(tail lst) · (cdr lst) | everything after the first |
(nth lst i) | 0-based |
(length lst) | |
(append a b) · (reverse lst) | |
(range from to) | end-exclusive |
(map f lst) | |
(filter f lst) | |
(reduce f init lst) | |
(sort-by f lst) | sort by a computed key |
(zip a b) | pairs |
(empty? lst) |
Literal syntax is {:key value …}. Every operation returns a new dict.
| Function | Notes |
|---|---|
(dict :k v …) | construct |
(dict-get d :k) | |
(dict-set d :k v) | → a new dict |
(dict-keys d) · (dict-values d) | |
(dict-has d :k) | |
(dict-merge a b) | later keys win |
| Function | Notes |
|---|---|
(type x) | the type as a string |
number? · string? · bool? · list? · nil? · symbol? · keyword? · fn? | predicates |
->string · ->number · ->bool | coercion |
(parse s) | read EELisp source into a value |
Times are epoch seconds; functions that take a date also accept a "YYYY-MM-DD" string.
| Function | Notes |
|---|---|
(now) | current time |
(today) | midnight today |
(date-format d pattern) | e.g. "EEEE", "yyyy-MM-dd" |
(date-add d n :days) | also :weeks, :months |
(date-diff a b :days) |
Date arithmetic is implemented in the engine — there is no external date dependency.
| Function | Notes |
|---|---|
(print x) · (println x) | captured by the host, not written to a terminal |
(eval form) | evaluate a value as code |
(apply f args) | call with a list of arguments |
(json-parse s) · (json-stringify v) | |
(http-get url) · (http-post url body) | synchronous; the only network access in the language |
Written in EELisp and loaded at startup — read it as worked examples of the language.
| Function | Notes |
|---|---|
id · inc · dec | |
even? · odd? · zero? · pos? · neg? | number predicates |
first · second · third · last | list access by position |
take · drop · count | |
some? · every? | does any / do all satisfy a predicate |
compose | combine two functions |
when · unless | macros with rest parameters |
| Function | Notes |
|---|---|
(deftable name (fields)) | name:type short form, or (name :type … :required … :default … :choices …) |
(insert table {dict}) | → the stored record, with its id |
(query table :where :params :order :asc :desc :limit :select) | → a result-set |
(records rs) | rows of a result-set, as a list |
(update table id {dict}) | |
(delete table id) | soft delete |
(pack table) | physically remove deleted rows |
(count-records table) | |
(tables) · (describe table) · (drop-table table) | |
(browse table) | a table view |
(edit table id) | a form view for one record |
(defform name table (field)…) | a named form, computed fields allowed |
(field-get r "name") · (field-set r "name" v) | |
(record-id r) |
Field types: string, number, bool, date.
| Function | Notes |
|---|---|
(add-item text :when :priority :category :notes) | |
(add-item-today text) | |
(add "call Bob tomorrow !!") | natural language; parses date, priority, people |
(smart-parse text) | the parse, without storing anything |
(items :search :category :priority :when-before :when-after) | |
(items-on date) · (items-between a b) | |
(item-get id) · (item-set id :k v) · (item-done id) | |
(item-count) | |
(every n :weeks) | recurrence — :days, :weeks, :months |
| Function | Notes |
|---|---|
(defcategory work/calls) | hierarchical; parents implied |
(assign id "path") · (unassign id "path") | |
(categories) | |
(defrule name :when … :assign … :action …) | :assign and :action may repeat |
(apply-rules) · (apply-rules id) | runs in a transaction; → number changed |
(auto-categorize true) | apply rules as items arrive |
(rules) · (drop-rule "name") |
Bound inside a rule condition: text, notes, id, categories, props, (get "f"), (has-category "c"), (overdue?), (match n).
| Function | Notes |
|---|---|
(defview name (:category … )) · (show name) | filtered, optionally grouped |
(views) · (drop-view "name") | |
(deftemplate name (…)) · (from-template name) | |
(templates) · (drop-template name) | |
(open-agenda "file.db") · (use-agenda name) · (close-agenda name) | isolated databases |
(agendas) | |
(export-agenda "f.json") · (import-agenda "f.json") | import runs in a transaction |
Installed by the host, so these exist when the engine runs inside an editor and not on the bare command line. They let a script read and change the document it is running in.
| Function | Notes |
|---|---|
(buffer-text) | the whole document |
(current-file) | path of the open note |
(cursor-pos) · (set-cursor n) | |
(selection) | the selected text |
(insert-at pos text) | |
(replace-range from to text) |
In EEditor, keybindings use a higher-level set of commands on top of these — see the keybinding reference.