Experiment with the Monkey programming language right here in your browser. MonkeyLab runs on WebAssembly and supports functional patterns like closures and higher-order functions.
Try out MonkeyLab directly in your browser with WebAssembly execution.
MonkeyLab compiles to WebAssembly for high-performance execution in the browser.
Based on the Monkey programming language with key extensions:
Powerful metaprogramming capabilities:
Designed for language theory experimentation:
MonkeyLab follows a C-like syntax similar to JavaScript.
Variables are declared using the let keyword:
let x = 5;
let y = "hello";
let z = true;
Standard if/else statements:
if (x > 5) {
return "greater";
} else {
return "less or equal";
}
Closure and recursion for iteration:
let fibonacci = fn(x) {
if (x < 2) {
return x;
} else {
return fibonacci(x - 1) + fibonacci(x - 2);
}
};
puts("Fibonacci sequence:");
let fibonacci_iter = fn(start, end) {
let iter = fn(i) {
if (i < end) {
puts(fibonacci(i));
iter(i+1);
}
}
iter(start);
}
fibonacci_iter(1, 10);
MonkeyLab has a simple but expressive type system:
Integer: Whole numbers (e.g., 42)Boolean: true or falseString: Text enclosed in quotes (e.g., "hello")Null: Represents absence of valueArray: Ordered collection (e.g., [1, 2, 3])HashMap: Key-value pairs (e.g., {"key": "value"})// Arrays
let numbers = [1, 2, 3, 4, 5];
let first = numbers[0]; // 1
let person = {"name": "Bob", "age": 30};
let name = person["name"]; // "Bob"
Functions are first-class citizens in MonkeyLab:
// Function declaration
let add = fn(a, b) {
return a + b;
};
let apply = fn(func, x, y) {
return func(x, y);
};
let makeCounter = fn() {
let count = 0;
return fn() {
count = count + 1;
return count;
};
};
let counter = makeCounter();
counter();
counter();
MonkeyLab extends the Monkey language with a powerful macro system:
// Define a simple macro
macro unless(condition, consequence, alternative) {
quote(
if (!(unquote(condition))) {
unquote(consequence);
} else {
unquote(alternative);
}
);
}
unless(10 > 5,
puts("not greater"),
puts("greater")
);
MonkeyLab provides a set of useful built-in functions:
puts(value) - Prints value to the console with a newlineprint(value) - Prints value without a newlinelen(array) - Returns the length of an arrayfirst(array) - Returns the first elementlast(array) - Returns the last elementrest(array) - Returns array without the first elementpush(array, element) - Adds element to the endmap(array, function) - Maps function over arrayreduce(array, function, initial) - Reduces arrayfilter(array, function) - Filters array by function
let fibonacci = fn(x) {
if (x < 2) {
return x;
} else {
return fibonacci(x - 1) + fibonacci(x - 2);
}
};
puts("Fibonacci sequence:");
let fibonacci_iter = fn(start, end) {
let iter = fn(i) {
if (i < end) {
puts(fibonacci(i));
iter(i+1);
}
}
iter(start);
}
fibonacci_iter(1, 10);
let start = 1;
let end = 100;
let fizzbuzz = fn (i) {
if (and(rem(i, 5) == 0, rem(i, 3) == 0 )) {
return "FizzBuzz";
}
if (rem(i, 5) == 0) {
return "Fizz";
}
if (rem(i, 3) == 0) {
return "Buzz";
}
return "";
};
let solveFizzBuzz = fn (s, e) {
if (s > e) {
return "";
}
let v = fizzbuzz(s);
if (!eq(v, "")) {
puts(join(s, " = ", v));
}
return solveFizzBuzz(s+1, e);
};
puts(start, end);
solveFizzBuzz(start, end);
let map = fn(arr, f) {
let iter = fn(arr, acc) {
if (len(arr) == 0) {
acc
} else {
iter(rest(arr), push(acc, f(first(arr))))
}
};
iter(arr, [])
};
let a = [1, 2, 3];
puts(join("original array: ", a), "");
let square = fn (x) {x * x};
puts(join("mapped array: ", map(a, square)));
let reduce = fn(arr, init, f) {
let iter = fn(arr, acc) {
if (len(arr) == 0) {
acc
} else {
iter(rest(arr), f(acc, first(arr)))
}
};
iter(arr, init);
};
let reduced = reduce(map(a, square), 0, fn(s, v) {s + v});
puts(join("Reduced Value = ", reduced))
let numbers = [1, 2, 3, 4, 5];
let doubled = map(numbers, fn(x) { return x * 2; });
puts("Doubled: ");
puts(doubled);
let sum = reduce(numbers, 0, fn(acc, x) { return acc + x; });
puts("Sum: ");
puts(sum);
let filter = fn (arr, f_fn) {
let iter = fn(arr, acc) {
if (len(arr) == 0) {
acc
} else {
if (f_fn(first(arr)) == true) {
iter(rest(arr), push(acc, first(arr)))
} else {
iter(rest(arr), acc)
}
}
}
iter(arr, [])
}
let evens = filter(numbers, fn(x) { return rem(x,2) == 0; });
puts("Even numbers: ");
puts(evens);