Features
Monkey is a feature-rich programming language that supports both imperative and functional programming paradigms. This section covers the main features that make Monkey a powerful and expressive language.
Variable Bindings
Variables in Monkey are created using let
statements:
let name = "Alice";
let age = 30;
let isStudent = false;
Variables are immutable once bound - you cannot reassign them:
let x = 5;
// x = 10; // This would cause an error
Functions
Functions are first-class citizens in Monkey, supporting both named and anonymous functions.
Function Definition
let add = fn(a, b) {
a + b;
};
let greet = fn(name) {
"Hello, " + name + "!";
};
Higher-Order Functions
Functions can take other functions as parameters and return functions:
let applyTwice = fn(f, x) {
f(f(x));
};
let double = fn(x) { x * 2; };
let result = applyTwice(double, 5); // 20
Closures
Functions capture their lexical environment, creating closures:
let makeCounter = fn() {
let count = 0;
fn() {
count = count + 1;
count;
};
};
let counter = makeCounter();
counter(); // 1
counter(); // 2
Conditional Expressions
Monkey uses if-else
expressions (not statements) that return values:
let max = fn(a, b) {
if (a > b) {
a;
} else {
b;
};
};
let status = if (age >= 18) { "adult" } else { "minor" };
Return Statements
Functions can use explicit return
statements:
let factorial = fn(n) {
if (n <= 1) {
return 1;
}
n * factorial(n - 1);
};
Recursion
Monkey supports recursive function calls:
let fibonacci = fn(n) {
if (n < 2) {
n;
} else {
fibonacci(n - 1) + fibonacci(n - 2);
}
};
Array Operations
Monkey provides rich array manipulation capabilities:
let numbers = [1, 2, 3, 4, 5];
// Functional array operations
let doubled = map(numbers, fn(x) { x * 2 });
let sum = reduce(numbers, 0, fn(acc, x) { acc + x });
let evens = filter(numbers, fn(x) { x % 2 == 0 });
Hash Map Operations
Hash maps provide key-value storage:
let person = {
"name": "Bob",
"age": 25,
"city": "New York"
};
let name = person["name"];
let hasAge = "age" in person; // Note: 'in' operator may not be implemented
String Manipulation
While Monkey doesn't have built-in string concatenation with +
, it provides
string operations through built-in functions:
let greeting = "Hello";
let name = "World";
// String operations would typically be done through built-in functions
let length = len(greeting); // 5
Error Handling
Monkey handles errors at runtime. Invalid operations will produce error messages:
let result = 5 / 0; // Runtime error
let invalid = {}[42]; // Runtime error for invalid hash access
Scoping
Monkey uses lexical scoping with proper variable shadowing:
let x = 10;
let outer = fn() {
let x = 20; // Shadows outer x
let inner = fn() {
let x = 30; // Shadows both outer x values
x;
};
inner(); // Returns 30
};
Expression-Oriented
Most constructs in Monkey are expressions that return values, making the language very composable:
let result = if (condition) {
fn(x) { x * 2 }(5)
} else {
10
};