Crates.io | lion |
lib.rs | lion |
version | 0.0.0 |
source | src |
created_at | 2016-06-19 03:24:07.172967 |
updated_at | 2016-06-19 03:24:07.172967 |
description | LION |
homepage | |
repository | https://github.com/sunjay/lion |
max_upload_size | |
id | 5419 |
size | 109,329 |
A very tiny, dynamic, loosely-typed language for doing calculations in a more intuitive way.
$ 2 + 2
= 4
$ 20 cm + 2 m
= 220 cm
$ (20 cm + 2 m) m
= 2.2 m
$ add2 x = x + 2
$ add2 5
= 7
$ add2cm x = x + 2 cm
$ add2cm (5 cm)
= 7 cm
Functions:
<function_name> <param1> <param2> = <expression>
\<param1> <param2> = <expression>
Expressions:
{ <expressions> }
where the result of the expression is the final line in the blockStrings: (but no string operators...yet)
Default operators:
+
-
*
/
**
==
!=
>=
<=
neg
- for negating numbers (since -
is infix)max
, min
, sin
, cos
, tan
, etc.All the basic operators will be defined in lion syntax in a special prelude module.
Defining an operator is as simple as calling the operator
function and passing in its three parameters:
PREFIX
, POSTFIX
, INFIX
"$$"
)PREFIX
and POSTFIX
operators take one parameterINFIX
operators take two parametersFunction declaration syntax is syntatic sugar for defining a PREFIX
operator with high precedence.
TODO: Everything is left-associative right now, this may be changed in later versions to be configurable
$ operator INFIX 6 "$$" (\x y = x * y + x)
$ 3 $$ 2
= 9
$ f x = 2 * x
$ operator POSTFIX 6 "timestwo" (f)
$ 2.5 timestwo
= 5
$ (2.5 cm) timestwo
= 5 cm
Units are simply POSTFIX
operators with a very high precedence. This section describes some useful functions introduced to make working with units easier.
Units can have any casing, but to avoid confusion it is recommended to always use proper SI prefixes (or whatever other system you are following) whenever possible.
The defineUnit
function takes a case-sensitive string (use double-quotes) representing the unit's name. This defines a tightly-bound (high precedence) POSTFIX
function which when used, attempts to convert its argument to the now defined unit based on any conversions that are currently defined.
$ defineUnit "kohm"
$ 3 kohm
= 3 kohm
All values with no unit are defined to have a special unit called units
. The conversion to this unit simply removes whatever unit a value already has. To convert from this unit to another one, the new unit just replaces units
as the unit for this value.
defineUnit
takes care of defining this simple conversion for you and immediately makes your unit available for use in simple conversions to and from units
.
The now defined unit function can be used as an argument in the convert
function. The convert
function is what is used behind the scenes to convert from the current unit of the quantity to a new unit.
# By wrapping the `cm` function in parentheses, it is not evaluated
$ convert (2 units) (cm)
Conversions are automatically performed during calculations. The units are combined such that the leftmost unit is preserved. Incompatible units (where no conversion can be resolved) are left untouched since they cannot be reduced any further.
$ 20 cm + 2 m
= 220 cm
$ 20 cm + 2 m + 2 kohm
= 220 cm + 2 kohm
You can explicitly convert to a unit by calling its function:
$ (20 cm + 2 m) m
= 2.2 m
This is equivalent to:
$ convert (20 cm + 2 m) (m)
= 2.2 m
This will only work if a conversion from cm
to m
is defined. The prelude
module loaded with each program session has many useful units and conversions already built in.
To define a conversion between two units, use the conversion
function.
The conversion
function takes the two units to convert from and to as well as a function to convert from the first argument to the second one. This conversion definition is one way. No equivalence is automatically defined.
$ conversion cm m (\x = x / 100)
Essentially does beta reduction on any given expression. Since the language is lazy, many advanced expressions can be supported without explicitly requiring lambdas everywhere (see if
below). Everything, including unit conversions must be lazy since many unit conversions can often be ruled out.
Certain functions will be defined on a "language level". Language level just means that these are immutable functions available at runtime.
Examples of lanaguage level functions:
operator
- for defining custom operators (See Custom Operators)defineUnit
- for defining a new unit (See Units), does not error if the unit already exists, creates a POSTFIX
function with the given name that attempts to resolve the given parameter to this unitconvert
- for giving some quantity a new unit, performs a conversionunitFor
- retrieves the unit for some quantityvalueOf
- retrieves the raw value (without a unit) for a given quantity, technically just performs a conversion to the unit units
conversion
- defines a conversion from one unit to another, overwrites any existing conversion (See Defining Conversions)if
- evaluates a given boolean expression and then returns one of its arguments based on the result
if <expr> <if_true> <if_false>
results in one of the expressions based on the result of expr
Fairly flexible because of how blocks work
Both parameters are required