A frinj-flavoured notation for commensura — an optional, familiar entry point for people coming
from the frinj library (Martin Trojer's Clojure port of Alan Eliasen's Frink). It is a thin sugar
layer: every value it builds is an ordinary commensura.quantity, so the exact tower, dimensions, and
printing all carry through — a conversion keeps its unit and dimension rather than flattening to a bare
number the way frinj does.
(require '[commensura.infix :refer [fj $= to]])
(fj 10 :feet 12 :feet 8 :feet :to :gallons) ;=> 552960/77 gallon ≈ 7181.30 [volume]
($= (fj 2 :tons) / (fj 10 :feet 12 :feet :water))
; a value you can keep computing with — no str needed
Two forms:
fj — keyword soup. A left-to-right product of alternating numbers and :unit keywords
((fj 5 12 :floz) ⇒ 60 floz); :per divides the next factor; :to converts everything after it to
a target built the same way. Unit keywords resolve through commensura.registry — with a plural
fallback (:gallons → gallon), since commensura registers singular names.$= — infix math over ** * / + - (→ pow/by/per/plus/minus) and the comparisons
== != < > <= >= (→ eq?/ne?/lt?/gt?/le?/ge?), with precedence ** > * / > + - >
comparisons. Add your own with defop. Operands are fj forms, numbers, or nested $=.to (a plain fn) converts an already-built quantity: (to q :dollars :per :day). A unit-led target
re-expresses in that unit (keeps the dimension); a number-led target — (to keg 12 :floz) — returns
the dimensionless count; a mirrored target whose dimension is the reciprocal of the source's is
flipped for you (frinj's "reverse mirrored units"), so (to fuel-per-distance :feet :per :gallon)
yields the economy. (This reversal is the frinj-flavoured layer's; commensura.core/to stays strict.)
Define your own units the ordinary commensura way — (defunit beer (fj 12 :floz 3.2 :percent :water :per :alcohol)) — and later soups resolve them by name ((fj :magnum 13.5 :percent :to :beer)); this
layer adds no separate registration path (frinj's add-unit! is just commensura.core/defunit).
Credit: the notation and the worked examples are Alan Eliasen's Frink and Martin Trojer's frinj; this namespace just re-points them at commensura's exact engine.
A **frinj-flavoured** notation for commensura — an optional, familiar entry point for people coming
from the `frinj` library (Martin Trojer's Clojure port of Alan Eliasen's Frink). It is a thin sugar
layer: every value it builds is an ordinary `commensura.quantity`, so the exact tower, dimensions, and
printing all carry through — a conversion keeps its unit and dimension rather than flattening to a bare
number the way frinj does.
(require '[commensura.infix :refer [fj $= to]])
(fj 10 :feet 12 :feet 8 :feet :to :gallons) ;=> 552960/77 gallon ≈ 7181.30 [volume]
($= (fj 2 :tons) / (fj 10 :feet 12 :feet :water))
; a value you can keep computing with — no `str` needed
Two forms:
* **`fj`** — *keyword soup*. A left-to-right product of alternating numbers and `:unit` keywords
(`(fj 5 12 :floz)` ⇒ 60 floz); `:per` divides the next factor; `:to` converts everything after it to
a target built the same way. Unit keywords resolve through `commensura.registry` — with a plural
fallback (`:gallons` → `gallon`), since commensura registers singular names.
* **`$=`** — *infix math* over `** * / + -` (→ `pow`/`by`/`per`/`plus`/`minus`) and the comparisons
`== != < > <= >=` (→ `eq?`/`ne?`/`lt?`/`gt?`/`le?`/`ge?`), with precedence `**` > `* /` > `+ -` >
comparisons. Add your own with **`defop`**. Operands are `fj` forms, numbers, or nested `$=`.
`to` (a plain fn) converts an already-built quantity: `(to q :dollars :per :day)`. A *unit-led* target
re-expresses in that unit (keeps the dimension); a *number-led* target — `(to keg 12 :floz)` — returns
the dimensionless **count**; a *mirrored* target whose dimension is the reciprocal of the source's is
flipped for you (frinj's "reverse mirrored units"), so `(to fuel-per-distance :feet :per :gallon)`
yields the economy. (This reversal is the frinj-flavoured layer's; `commensura.core/to` stays strict.)
Define your own units the ordinary commensura way — `(defunit beer (fj 12 :floz 3.2 :percent :water
:per :alcohol))` — and later soups resolve them by name (`(fj :magnum 13.5 :percent :to :beer)`); this
layer adds no separate registration path (frinj's `add-unit!` is just `commensura.core/defunit`).
Credit: the notation and the worked examples are Alan Eliasen's Frink and Martin Trojer's frinj; this
namespace just re-points them at commensura's exact engine.($= & tokens)Infix over quantities: ($= (fj 4/3 :pi) * (fj 250 :km) ** 3). Operators come from the defop table
— arithmetic ** * / + - (→ pow/by/per/plus/minus) and comparisons == != < > <= >= (→
eq?/ne?/lt?/gt?/le?/ge?) — with precedence ** > * / > + - > comparisons, all left-associative.
Operands are fj forms, numbers, or nested $= (which also groups a sub-expression).
Infix over quantities: `($= (fj 4/3 :pi) * (fj 250 :km) ** 3)`. Operators come from the `defop` table — arithmetic `** * / + -` (→ pow/by/per/plus/minus) and comparisons `== != < > <= >=` (→ eq?/ne?/lt?/gt?/le?/ge?) — with precedence `**` > `* /` > `+ -` > comparisons, all left-associative. Operands are `fj` forms, numbers, or nested `$=` (which also groups a sub-expression).
(defop op prec f)Define an infix operator usable inside $=: (defop <sym> <precedence> <fn>), higher precedence
binding tighter, <fn> a binary function named by a resolvable symbol. Mirrors frinj's defop — the
builtins below register themselves this way, and user operators join them at load time.
Define an infix operator usable inside `$=`: `(defop <sym> <precedence> <fn>)`, higher precedence binding tighter, `<fn>` a binary function named by a resolvable symbol. Mirrors frinj's `defop` — the builtins below register themselves this way, and user operators join them at load time.
(fj & tokens)Build a quantity from keyword soup: (fj 10 :feet 12 :feet 8 :feet) ⇒ 960 feet³. :per divides the
next factor; a trailing :to <target soup> converts the result (see the ns docstring).
Build a quantity from *keyword soup*: `(fj 10 :feet 12 :feet 8 :feet)` ⇒ 960 feet³. `:per` divides the next factor; a trailing `:to <target soup>` converts the result (see the ns docstring).
(register-op! op prec fn-sym)Install an infix operator for $=: op symbol → precedence + a binary fn (a resolvable symbol).
Prefer the defop macro.
Install an infix operator for `$=`: `op` symbol → precedence + a binary fn (a resolvable symbol). Prefer the `defop` macro.
(to source & target-tokens)Convert an already-built quantity to a soup target: (to (fj :keg) :case), (to q :dollars :per :day). Number-led targets give the dimensionless count ((to (fj :keg) 12 :floz) ⇒ 496/3).
Convert an already-built quantity to a soup target: `(to (fj :keg) :case)`, `(to q :dollars :per :day)`. Number-led targets give the dimensionless count (`(to (fj :keg) 12 :floz)` ⇒ 496/3).
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |