-
Notifications
You must be signed in to change notification settings - Fork 7
User Guide
If you haven't looked at the example calculations yet, start there. It will show the most common calculation patterns you might encounter.
Frinj values (or numbers) are slightly different from normal Clojure ones. They also hold the a unit of measure. Frinj uses a defrecord called fjv to represent the number + unit-of-measure data. All Frinj operators and converters operate on fjv-s.
One of the main goals Frinj is to marry Clojure idiomatic calculations with the fluent syntax provided by Frink. To do this, the frinj.calc namespace provides some helper functions to easily build and convert fjv's. The main function for this purpose is simply called fj
.
Frinj comes with a standard set of operators for fjv's.
fj*
, fj_
, fj+
, fj-
, fj**
, fj=
, fj<
, (fj<=)
, fj>
, (fj>=)
Please note that these operators also work on normal Clojure numbers.
fj takes a parameter list which consist of numbers, units and operators. Here is some examples
-
(fj 1)
give a unit-less value of one -
(fj 1 :inch)
gives a value representing one inch -
(fj 10 :miles :per :hour)
10 miles/hour
Please note the multiplication is implicit if not :per
is used, so (fj 10 :miles :hour)
will give a value with a m*s unit instead of a m/s unit
-
(fj 10 1/2 :pi)
gives a value of 5*pi (again implicit multiplication) -
(fj 1 :cm)
gives a value of 1/100 m. This uses prefixes, see the [units] (https://github.com/martintrojer/frinj/wiki/Units) page for more details
You can also convert with fj
:
-
(fj :cm :to :inch)
give the value of how much 1 cm is in inches
So what if you want to add some values? Frinj has Clojure idiomatic functions for add, sub, mul, div, power and compare of fjv's.
-
(fj+ (fj 2 :inches) (fj :cm))
adds 2 inches and one cm -
(fj_ (fj 25 :miles) (fj 2 :hours))
divides, in this case calculates a velocity -
(fj= (fj :inches) (fj :meters) (fj :feet))
false; inches, meters and feet are not the same
The frinj operator will take normal numbers as parameters aswell and convert to unit-less fjv on the fly.
(fj* (fj :pi) 10)
gives 10*pi
The :to
operator is quite limited, if you want to convert to more advanced types you need to use the to
function.
to
takes multiple parameters, the first is the fjv you want to convert from. The rest are a list operands (very much like one for fj
.
;; If you took the matter in a teaspoon of water, and converted that to energy, how many gallons of gasoline would that equal?
(-> (fj :teaspoon :water :c :c) (to :gallons :gasoline) str)
If you want to convert the result of a f+, f* etc you cannot do it with (fj :to)
but rather use the to
function.
;; What if you knew that your floor could only support 2 tons? How deep could you fill the room with water?
(-> (fj_ (fj 2 :tons)
(fj 10 :feet 12 :feet :water))
(to :feet))
fj
have a specific operator for expressing dates, :#yyyy-MM-dd
. This will be converted to a value of units "s" representing the number of seconds since EPOC.
(fj- (fj :#2001-06-30) (fj :#2000-12-31))
give the time delta between those two dates
The operator :#now
gives the current time.
Finally there is a special function for transforming a the fjv back to a date string; to-date
(to-date (fj :#2001-06-30))
Frinj will do implicit inversion when converting fjv's.
(-> (fj 10 :hours :per :mile) (to :miles :per :hour))
gives 1/10.
Other than in this simple case, the units must match when converting.
If you're starting on a Frinj REPL session, consider running the function (override-operators!)
.
This will override clojure built in +
, -
etc operators with fj+
, fj-
etc. This will in effect make all REPL operations have units.
It also makes fjv print nicely.