Skip to content

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

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 */

Back to Top

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.

Back to Top

Variables & Scope

Variable declaration, assignment, and scope management.

Assignment

  • = - Basic assignment
  • += - Append to arrays
  • global - Declare global variable
  • local - Declare local variable
  • const - Declare constant

Examples

name = "Grapa";
count = 42;
numbers = [1, 2, 3];
numbers += 4;  /* Append to array */

Back to Top

Data Structures

Create and manipulate arrays, lists, and objects.

Array Operations

  • [item1, item2, ...] - Create array
  • += - Append to array
  • len() - Get array length
  • sum() - Sum array elements
  • mean() - 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"} */

Back to Top

Search & Analysis

Search, sort, and analyze data.

Search Functions

  • grep(pattern, options) - Search text with regex
  • search(data, pattern) - Search in data structures
  • findall(text, pattern) - Find all matches

Analysis Functions

  • sort(data) - Sort data
  • unique(data) - Remove duplicates
  • group(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] */

Back to Top

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

Back to Top

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 and filter 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 and filter 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

Back to Top

Type & I/O

Type checking, conversion, and input/output operations.

Type Functions

  • type(value) - Get type of value
  • int(value) - Convert to integer
  • float(value) - Convert to float
  • str(value) - Convert to string
  • bool(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();

Back to Top

Math Operations

Mathematical functions and operations.

Basic Math

  • +, -, *, / - Arithmetic operators
  • pow(base, exponent) - Power function
  • abs(value) - Absolute value
  • mod(value, divisor) - Modulo operation

Constants

  • pi - Pi constant
  • e - Euler's number

Examples

result = 4 * 3;
power = pow(2, 10);
absolute = abs(-42);
remainder = mod(17, 5);

Back to Top

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(" - ");

Back to Top

Array/Matrix Operations

Array and matrix manipulation.

Array Functions

  • shape(array) - Get array dimensions
  • reshape(array, dimensions) - Reshape array
  • sum(array) - Sum elements
  • mean(array) - Calculate mean

Matrix Functions

  • dot(matrix1, matrix2) - Matrix multiplication
  • t(matrix) - Transpose matrix

Examples

data = [1, 2, 3, 4, 5, 6];
matrix = reshape(data, [2, 3]);
transposed = t(matrix);

Back to Top

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();
}

Back to Top

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 */

Back to Top


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.

Back to Top