Moon
Moon is an minimal, JIT-compilable, portable and secure code-interchange format. It is:
-
Safe: Moon isolates logic from side-effects, allowing you to securely run code from untrusted sources.
-
Fast: when compiled to JS, it beats popular libs by a large margin.
-
Compact: Moon has a canonical binary format for very small bundles.
-
Decentralized: Moon imports are hash-addressed, recursively resolved from IPFS.
-
Small: this entire implementation, for example, is a 7.5K JS file (gzipped).
Formally, Moon is just untyped λ-calculus extended with numbers, strings and maps.
Usage / Examples
Running code
To evaluate some code, simply use Moon.run()
:
const Moon = ; const program = ` maximum = array => (for 0 (get array "length") 0 index => result => value = (get array (stn index)) (if (gtn value result) value result)) (maximum [1 7 6 9 5 2 8])`; console;
This is safe to do no matter the code contents, because Moon runs fully sandboxed.
Compiling Moon to a native function
You can also JIT-compile it to fast native functions:
const Moon = ; const factorial = Moon; console;
Decompiling a native function to Moon
And the other way around:
const Moon = ; const pair = Moon; console;
Loading code from IPFS
Moon can recursivelly import hash-addressed terms from IPFS:
const Moon = ; async { const sum = Moon; console; };
Saving code to IPFS
It can also easily publish those terms:
const Moon = ; async { const cid = await Moon; console; const double = Moon; console; };
Performing side-effects (IO)
Moon itself is pure, but it can perform side-effective computations by injecting the effects from the host language. To avoid the "callback-hell", you can use Moon's monadic notation:
do = zb2rhkLJtRQwHz9e5GjiQkBtjL2SzZZByogr1uNZFyzJGA9dX askPowerLevel = loop@ | power =< do "prompt" "What is your power level? " if 9000 | do "print" "No, it is not."> loop 0 | do "print" "Ah, that's cute!"> do "stop" askPowerLevel 0
You can run the code above using moon-tool:
moon runio zb2rhjR4sMEiMQ9m9bNCnavSUjEDzUvSrtAhuJStRWHcvNzb8
Optimizing code
-
Use
#
to fully inline an expression. -
Use
{fast:true}
option (faster, only tradeoff is it can't be decompiled). -
Don't use recursive algorithms (map, reduce, etc.) directly on arrays; convert to churh-lists to enable fusion.
async { // Notice the hash (#): it fully inlines an expression, making it 8x faster.const dotCode = `# x0 => y0 => z0 => x1 => y1 => z1 => Array = zb2rhYmsjmQuJivUtDRARcobLbApVQZE1CwqhfnbBxmYuGpXx a = [x0 y0 z0] b = [x1 y1 z1] (Array "sum" (Array "zipWith" (mul) a b))`; // Also, use {fast:true}const dot = Moon; // Call it a ton of timesvar dots = 0;for var i = 0; i < 1000000; ++i dots += 23456;console; // Check the difference on the outputconsole; };
Exporting Moon libs to npm
CLI
Check out moon-tool.
TODO
- Time limit option