-
Notifications
You must be signed in to change notification settings - Fork 3
Operator To Function
Most Khepri builtin operators, and all user defined operators, can be converted to a function by wrapping the operator in parentheses:
var add = (+);
add(1, 2); // 3
This allows operators to be passed directly to functions:
[1, 2, 3].reduce((+), 0); // 6
See dot expressions for creating partially applied accessor expressions such as:
var getX = (.x);
getX { x : 3}; // 3
As shorthand for partially applying a binary operator, you can include a curried argument in the parentheses. For all operators except binary .
and new
, the comma between the operator and the argument is optional
var add10 = (+ 10); // could also write (+, 10)
add10(2); // 12
Currying always curries the first arguments of the operator.
Application and curried operators work fine, but have a syntax that may be confusing coming from Javascript.
var f = \x -> x;
// These are the same
f (+);
f ( (+) );
// The curried operator is always passed as the argument
f (+, 1);
f ( (+, 1) );
// You can change this behavior be wrapping the argument list in parens
f ((+), 1);
You can flip a binary operator's arguments by prefixing the operator with _
. Used with currying, this allows the second argument of a binary operator to be curried (think of _
as the placeholder where the function input will go).
var div10 = (_ / 10);
div10 60; // 6
For all ops except the keyword operators new
and instanceof
, the space between _
and the operator is optional.
(_ / 10); // no space needed
(_ new, 10); // Without space this becomes` (_new, 10)` where `_new` is an identifier.
The following operators can be converted to functions (along with any user user defined operator derived from these operators).
Note that logical operators, like regular functions, do not use short-circuit evaluation once they are converted to functions.
typeof
void
~
!
++
--
instanceof
*
/
+
-
%
<<
>>
>>>
<
>
<=
>=
==
===
!=
!==
&&
||
??
|>
<|
\>
\>>
<\
<<\
-
.
- Computed membera.(b)
-
@
- Binary curry only.a @ b
-
new
- Binary version only.new a b
?
Converting an operator to a function will add at most one declaration per operator to the header of the output file:
// Input
foldl @ (+) @ 0;
// Output
var __add = \x y -> x + y;
foldl.bind(null, __add, 0);
Uncurried operators therefore evaluate to simple object references, and can be used with very little overhead
// Input
// In the body of the for loop, `(+)` is just a reference and
// does not declare a new function every iteration
for (var i = 0; i < 10000; i = i + 1)
f(i, (+));
// Output
var __add = \x y -> x + y;
for (var i = 0; i < 10000; i = i + 1)
f(i, __add);
Multiple instances of a single, uncured operator will always reference the same function in a file, but not across multiple files. Although you can safely set properties or perform equality tests on converted operators within a file, this behavior is not recommended.
Inlining is used for converted operators, and converted operators that inlining makes unreachable will not be added to the header.
// Input ----
(+)(2, 3);
(+, 2);
// Output ----
6;
\y -> 2 + y;