Grapa API Reference
For High-Level Grapa Programmers: This reference covers the functions and types you'll use most often when writing Grapa scripts and applications.
For Advanced Users: See the maintainer documentation for low-level functions, grammar development, and internal APIs.
Table of Contents
- Core Language
- Dynamic Code Execution
- Variables & Scope
- Data Structures
- Search & Analysis
- Control Flow
- Functional Programming
- Type & I/O
- Math Operations
- String Operations
- Array/Matrix Operations
- File System
- Time & Date
- Universal Object Methods
Core Language
Essential language constructs for writing Grapa scripts.
Comments
Grapa supports both block comments (/* ... */
) and line comments (// ...
). #
comments are not supported.
Comment Rules:
- Comments can be used anywhere in your code, including at the end of lines
- Comments work inside {}
blocks, class definitions, and function bodies
/* ✅ Correct */
x = 5; /* This works outside {} */
if (condition) {
/* This comment is correct */
x = 5;
}
/* ❌ Incorrect */
if (condition) {
x = 5; /* This will cause a syntax error */
}
Type System
Grapa uses dynamic typing with rich runtime type introspection. Everything in Grapa is data - functions, classes, primitives, and everything else are just different data types that can be manipulated, stored, and passed around.
Dynamic Typing with Runtime Safety
Grapa's type system provides the flexibility of dynamic typing with the safety of runtime type checking:
/* Dynamic type assignment */
x = 42; /* $INT */
x = "hello"; /* $STR */
x = [1, 2, 3]; /* $ARRAY */
/* Runtime type checking */
if (x.type() == $ARRAY) {
/* Safe to use array methods */
result = x.map(op(item) { item * 2; });
}
Type Introspection
Every value in Grapa supports type introspection:
/* Get type information */
value = 42;
type = value.type(); /* $INT */
/* Type comparison */
if (value.type() == $INT) {
/* Handle integer */
} elseif (value.type() == $STR) {
/* Handle string */
}
Unified Data Model
Grapa's unified data model means everything is a data type:
/* Functions are data */
func = op(x) { x * 2; };
func_type = func.type(); /* $OP */
/* Classes are data */
class_obj = $ARRAY;
class_type = class_obj.type(); /* $CLASS */
/* Rules are data */
rule_obj = rule <$expression> '+' <$expression> {@<add,{$1,$3}>};
rule_type = rule_obj.type(); /* $RULE */
Type Conversion
Grapa provides automatic and explicit type conversion:
/* Automatic conversion */
result = "42".int() + 8; /* 50 */
/* Explicit conversion */
str_value = 42.str(); /* "42" */
int_value = "42".int(); /* 42 */
float_value = "3.14".float(); /* 3.14 */
Type Safety Patterns
Best practices for type safety in Grapa:
/* Defensive programming */
process_data = op(data) {
if (data.type() != $ARRAY) {
return $ERR("Expected array");
}
/* Safe to process as array */
return data.map(op(item) { item * 2; });
};
/* Type checking with fallbacks */
safe_get = op(obj, key) {
if (obj.type() != $LIST) {
return null;
}
value = obj[key];
if (value.type() == $ERR) {
return null;
}
return value;
};
Core Type Methods
.type()
- Get the type of an object (returns$STR
).str()
- Convert to string.int()
- Convert to integer.float()
- Convert to float.bool()
- Convert to boolean
Language Extensibility
Grapa's most powerful feature is its ability to extend the language syntax at runtime. You can define custom commands and functions that become part of the language grammar.
Key Concepts:
- custom_command
: For commands that perform actions (no return value)
- custom_function
: For functions that return values
- Scoping: Local (function-level) or global (permanent) syntax extensions
- Dynamic Compilation: New syntax applies to code compiled with op(parse)()
/* Define custom syntax */
custom_function = rule select $INT {op(p:$2){p*5}};
/* Use it as if it were built into the language */
select 4; // Returns 20
x = select 8; // x = 40
For comprehensive documentation, see Language Syntax Extension.
Namespace System
Grapa has a dynamic namespace system managed by the execution tree:
$global
- Global namespace for persistent variables$local
- Local namespace (automatic for each function)- Automatic namespace creation for each execution context
- Hierarchical access to variables from parent namespaces
/* Global variables */
$global.config = {"debug": true};
/* Function with local namespace */
func = op(x) {
local_var = x * 2; /* In function's local namespace */
global_var = config; /* Access global namespace */
local_var.echo();
};
Basic Operations
.echo()
- Output text to console (method on strings/values).debug(level, component?)
- Output debug messages (requires-d
flag).\n
- Exit console (in interactive mode)sleep(seconds)
- Pause execution
Comments
/* This is a block comment */
/* Both block and line comments are supported in Grapa */
Dynamic Code Execution
Grapa's most powerful feature is its ability to compile and execute code at runtime. This enables advanced meta-programming patterns.
Core Functions
op()(script)
- Compile string to executable function$sys().eval(script, params)
- Evaluate script with parameters$sys().compile(script)
- Pre-compile script for performance
Examples
/* Direct string execution */
op()("'Hello, World!'.echo();")();
/* Output: Hello, World! */
/* With parameters */
func = op("name"=0)("'Hello, ' + name + '!'.echo();");
func("Grapa");
/* Output: Hello, Grapa! */
/* System-level evaluation */
result = $sys().eval("x + y", {"x": 5, "y": 3});
result.echo(); /* 8 */
/* Compiled execution for performance */
compiled = $sys().compile("input * 2 + offset");
result = $sys().eval(compiled, {"input": 10, "offset": 5});
result.echo(); /* 25 */
/* Dynamic function generation */
operations = ["add", "sub", "mul"];
funcs = {};
i = 0;
while (i < operations.len()) {
op_name = operations.get(i);
code = "a " + op_name + " b";
funcs[op_name] = op("a"=0, "b"=0)(code);
i += 1;
}
/* Execute generated functions */
funcs["add"](5, 3).echo(); /* 8 */
funcs["mul"](5, 3).echo(); /* 15 */
Note: This is Grapa's core meta-programming capability, making it superior to most languages for dynamic code execution.
Variables & Scope
Variable declaration, assignment, and scope management.
Assignment
=
- Basic assignment+=
- Append to arraysglobal
- Declare global variablelocal
- Declare local variableconst
- Declare constant
Examples
name = "Grapa";
count = 42;
numbers = [1, 2, 3];
numbers += 4; /* Append to array */
Data Structures
Create and manipulate arrays, lists, and objects.
Array Operations
[item1, item2, ...]
- Create array+=
- Append to arraylen()
- Get array lengthsum()
- Sum array elementsmean()
- Calculate mean
List/Object Operations
{key: value, ...}
- Create list/object.key
- Access object property.keys()
- Get object keys.values()
- Get object values
Object Merging Operators
+=
- Append/nest second object within first++=
- Merge/flatten properties from both objects. For rules, concatenates additional rule alternatives (see Rule Composition)
Examples
/* Arrays */
numbers = [1, 2, 3, 4, 5];
numbers += 6;
total = numbers.sum();
average = numbers.mean();
/* Objects */
config = {"host": "localhost", "port": 8080};
host = config.host;
/* Object merging */
user = {"name": "John"};
profile = {"age": 30, "email": "john@example.com"};
/* Append (nested) */
user += profile;
user.echo(); /* {"name":"John",{"age":30,"email":"john@example.com"}} */
/* Merge (flattened) */
user = {"name": "John"};
user ++= profile;
user.echo(); /* {"name":"John","age":30,"email":"john@example.com"} */
Search & Analysis
Search, sort, and analyze data.
Search Functions
grep(pattern, options)
- Search text with regexsearch(data, pattern)
- Search in data structuresfindall(text, pattern)
- Find all matches
Analysis Functions
sort(data)
- Sort dataunique(data)
- Remove duplicatesgroup(data, key)
- Group data by key
Examples
text = "Hello world\nGoodbye world";
matches = text.grep("world", "o"); /* ["world", "world"] */
data = [3, 1, 4, 1, 5];
sorted_data = data.sort(); /* [1, 1, 3, 4, 5] */
unique_data = data.unique(); /* [3, 1, 4, 5] */
Control Flow
Control program execution and logic flow with proper propagation through all execution contexts.
Conditionals
if (condition) {
/* code */
} else {
/* code */
}
Loops with Control Flow
/* While loop with break and continue */
i = 0;
while (i < 5) {
if (i == 3) {
break; /* Exit loop immediately */
};
if (i == 1) {
i += 1;
continue; /* Skip to next iteration */
};
("Iteration " + i.str()).echo();
i += 1;
};
/* For loop with control flow */
for (i = 0; i < 5; i += 1) {
if (i == 3) {
break; /* Exit loop immediately */
};
if (i == 1) {
continue; /* Skip to next iteration */
};
("Iteration " + i.str()).echo();
};
Functions with Control Flow
/* Function with return statements */
my_function = op(a, b) {
if (a < 0) {
return 0; /* Early return */
};
if (b == 0) {
return a; /* Early return */
};
return a / b; /* Normal return */
};
/* Function with exit */
critical_function = op() {
if (error_condition) {
exit; /* Terminate program */
};
return "success";
};
Switch Statements
/* Switch with control flow */
switch (value) {
case 1: return "one";;
case 2: return "two";;
default: return "unknown";;
}
Control Flow in Inline Code Blocks
/* Control flow in inline code blocks */
"hi".{if (true) return 999; x=@$$; x.len()}.range(); /* Returns 999 */
/* Control flow propagates through all contexts */
func test() {
"hi".{if (true) return 999; x=@$$; x.len()}.range();
return 888;
};
test(); /* Returns 999 */
Control Flow Propagation
All control flow statements properly propagate through all execution contexts:
- Functions: RETURN statements exit functions and propagate return values
- Loops: BREAK exits loops, CONTINUE skips to next iteration
- Switches: RETURN statements exit switch statements
- Inline Code Blocks: Control flow properly terminates block execution
- Reduce Operations: Control flow properly terminates reduce and propagates values
- Nested Contexts: Control flow propagates through all nested execution contexts
Functional Programming
Parallel and sequential data processing functions.
Map, Filter, Reduce
map(data, function)
- Apply function to each element (parallel)filter(data, function)
- Filter elements (parallel)reduce(data, function, [initial])
- Reduce to single value (sequential)
Examples
data = [1, 2, 3, 4, 5];
/* Map (parallel) */
doubled = data.map(op(x) { x * 2; });
/* Filter (parallel) */
evans = data.filter(op(x) { x % 2 == 0; });
/* Reduce (sequential) - with initializer */
sum = data.reduce(op(acc, x) { acc + x; }, 0);
/* Reduce (sequential) - without initializer */
sum = data.reduce(op(acc, x) { acc + x; });
/* Reduce with control flow */
result = data.reduce(op(acc, x) {
if (x == 3) return 999; /* Early return */
if (x == 4) break; /* Early termination */
acc + x;
}, 0);
Note:
map
andfilter
are parallel by default and production-ready for high-throughput data processing.reduce
supports all control flow statements (break, return, throw) with proper propagation.map
andfilter
support.throw()
(collects all results in array),.return()
(returns value for specific item), and.break()
(returns empty string for specific item). All functional methods now have complete control flow support with enhanced error collection.
Advanced Functional Programming: Complex Context Objects
Functional methods support any data structure as initializers, enabling sophisticated state machines and context-aware operations:
/* Stateful reduction with dynamic operation switching */
[1, 2, 3].reduce(op(x, y) {
if (y == 2) x.o = op(a, b) { a * b; }; /* Switch to multiplication */
x.st = x.o(x.st, y); /* Apply current operation */
}, {st: 10, o: op(a, b) { a + b; }}); /* Initial state object */
/* Map with context tracking */
[1, 2, 3].map(op(x, y) {
y.count += 1;
y.sum += x;
x * y.multiplier;
}, {count: 0, sum: 0, multiplier: 2});
/* Filter with state management */
[1, 2, 3, 4, 5].filter(op(x, y) {
y.seen += 1;
if (y.seen <= 3) {
y.sum += x;
true;
} else {
false;
};
}, {seen: 0, sum: 0});
Key Capabilities: - Any Data Structure: Use objects, lists, arrays as initializers - Context Evolution: Data structures can evolve during operations - Dynamic Operations: Functions can be stored and modified within context - State Machines: Build complex state machines with multiple operations - Pipeline Processing: Create sophisticated data processing workflows
Design Philosophy: Grapa's dynamic typing enables this flexibility by leaving type handling to the implementation rather than enforcing strict type constraints. This allows runtime type evolution, dynamic function assignment, and context-aware processing where types emerge from usage patterns.
Concurrency Coordination with Functional Methods
Grapa's .map()
and .filter()
methods can be used as thread synchronization barriers for coordinating multiple worker threads:
/* Worker thread coordination */
workers = [1, 2, 3, 4, 5].map(op(worker_id) {
/* Each worker does independent work */
("Worker " + worker_id.str() + " starting").echo();
sleep(worker_id); /* Simulate work */
("Worker " + worker_id.str() + " completed").echo();
worker_id * 100; /* Return result */
});
/* All workers complete before proceeding */
("All workers finished").echo();
/* Parallel task execution */
tasks = [
op() { "Task A: Database query".echo(); sleep(2); "A done".echo(); },
op() { "Task B: API call".echo(); sleep(1); "B done".echo(); },
op() { "Task C: File processing".echo(); sleep(3); "C done".echo(); }
];
results = tasks.map(op(task) { task(); });
/* All tasks complete before proceeding */
("All tasks completed").echo();
Key Benefits: - Structured Concurrency: Automatic synchronization barrier - Worker Coordination: Perfect for parallel task execution - Resource Management: Coordinate multiple resource operations - System Initialization: Parallel component initialization - No Manual Thread Management: Automatic coordination and cleanup
Type & I/O
Type checking, conversion, and input/output operations.
Type Functions
type(value)
- Get type of valueint(value)
- Convert to integerfloat(value)
- Convert to floatstr(value)
- Convert to stringbool(value)
- Convert to boolean
I/O Functions
.echo()
- Output to console (method on strings/values)prompt(message)
- Get user input
Examples
value = "42";
number = int(value);
text = str(number);
name = prompt("Enter your name: ");
("Hello, " + name).echo();
Math Operations
Mathematical functions and operations.
Basic Math
+
,-
,*
,/
- Arithmetic operatorspow(base, exponent)
- Power functionabs(value)
- Absolute valuemod(value, divisor)
- Modulo operation
Constants
pi
- Pi constante
- Euler's number
Examples
result = 4 * 3;
power = pow(2, 10);
absolute = abs(-42);
remainder = mod(17, 5);
String Operations
String manipulation and analysis.
String Methods
.len()
- Get string length.upper()
- Convert to uppercase.lower()
- Convert to lowercase.casefold()
- Convert to Unicode case folded form (for case-insensitive comparisons).trim([chars])
- Remove characters from both ends (default: space).ltrim([chars])
- Remove characters from left end (default: space).rtrim([chars])
- Remove characters from right end (default: space).split(delimiter)
- Split string.join(array)
- Join array into string.replace(old, new)
- Replace text.grep(pattern, options)
- Search with regex
See Also: String Templates and Dynamic Construction for advanced string construction patterns using templates, dynamic execution, and parameterized functions.
Examples
text = " Hello, World! ";
length = text.len();
upper = text.trim().upper();
words = text.split(", ");
joined = words.join(" - ");
Array/Matrix Operations
Array and matrix manipulation.
Array Functions
shape(array)
- Get array dimensionsreshape(array, dimensions)
- Reshape arraysum(array)
- Sum elementsmean(array)
- Calculate mean
Matrix Functions
dot(matrix1, matrix2)
- Matrix multiplicationt(matrix)
- Transpose matrix
Examples
data = [1, 2, 3, 4, 5, 6];
matrix = reshape(data, [2, 3]);
transposed = t(matrix);
File System
File and directory operations.
File Operations
$file().getfield(path)
- Read file content$file().setfield(path, content)
- Write to file$file().ls(path)
- List directory contents$file().info(path)
- Get file information
Examples
/* Read file */
content = $file().getfield("data.txt");
/* Write file */
$file().setfield("output.txt", "Hello from Grapa!");
/* List files */
files = $file().ls(".");
for (file in files) {
("File: " + file.name).echo();
}
Time & Date
Time and date utilities.
Time Functions
$time()
- Get current timestamp$time().format(format)
- Format timestamp$time().add(seconds)
- Add time$time().sub(seconds)
- Subtract time
Examples
now = $time();
formatted = now.format("%Y-%m-%d %H:%M:%S");
tomorrow = now.add(86400); /* Add 24 hours */
Universal Object Methods
All Grapa objects support a comprehensive set of methods through the $OBJ
class. These methods provide type conversion, manipulation, and utility functions that work on any data type.
Key Method Categories
- Type Conversion:
.float()
,.int()
,.str()
,.bool()
,.base()
- String Manipulation:
.left()
,.right()
,.mid()
,.trim()
,.replace()
,.interpolate()
- Array Operations:
.split()
,.join()
,.sort()
,.unique()
,.group()
- Functional Programming:
.map()
,.filter()
,.reduce()
,.range()
- Search & Pattern:
.grep()
,.match()
,.findall()
- Bit Manipulation:
.setbit()
,.clearbit()
,.genbits()
- Cryptography:
.encode()
,.decode()
,.sign()
,.verify()
,.secret()
- Universal Access:
.get()
,.set()
- works across$ARRAY
,$LIST
,$OBJ
,$file
,$TABLE
,$WIDGET
- Flexible Field Access:
.getfield()
,.setfield()
- universal methods (mix/match of names and indices for$ARRAY
,$LIST
, and$OBJ
non-system classes only) - Utilities:
.echo()
,.debug()
,.iferr()
,.exec()
,.getname()
Quick Examples
/* Type conversion with precision */
result = "3.14159".float(4, 0).base(16);
/* String processing pipeline */
text = " Hello, World! ";
processed = text.trim().upper().replace("WORLD", "GRAPA");
/* Functional array processing */
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
result = data
.filter(op(x) { x % 2 == 0; })
.map(op(x) { x * x; })
.reduce(op(acc, x) { acc + x; }, 0);
Universal .get()/.set() Methods
The universal .get()
and .set()
methods provide consistent access patterns across multiple data types:
/* $ARRAY examples */
my_array = [1, 2, 3, 4, 5];
my_array.set(2, 99);
value = my_array.get(2); /* 99 */
/* $LIST examples */
my_list = {"name": "Alice", "age": 30};
my_list.set("name", "Bob");
name = my_list.get("name"); /* "Bob" */
/* $OBJ examples */
my_obj = {};
my_obj.set("property", "value");
value = my_obj.get("property"); /* "value" */
/* $file examples */
my_file = $file();
my_file.set("test.txt", "Hello World");
content = my_file.get("test.txt"); /* "Hello World" */
/* $TABLE examples */
my_table = {}.table("ROW");
my_table.mkfield("name", "STR", "VAR");
my_table.set("user1", "name", "Alice");
name = my_table.get("user1", "name"); /* "Alice" */
Supported Types:
- $ARRAY
: array.get(index)
, array.set(index, value)
- 0-based indexing
- $LIST
: list.get(key)
, list.set(key, value)
- $OBJ
: obj.get(key)
, obj.set(key, value)
- $file
: file.get(key)
, file.set(key, value)
- $TABLE
: table.get(key, field)
, table.set(key, field, value)
- $WIDGET
: widget.get(name, params)
, widget.set(name, data)
For complete documentation of all $OBJ
methods with their parameters and examples, see $OBJ Methods Reference.