Functions, Flow & Streaming
Functions, Flow & Streaming
Section titled “Functions, Flow & Streaming”Function Definitions
Section titled “Function Definitions”Functions are the main way to organize your NSL code. They are defined at the top level of your file.
// ReturnType functionName(Type param1, Type param2) { body }int add(int a, int b) { return a + b;}Default Arguments
Section titled “Default Arguments”You can provide default values for parameters. They must come at the end of the list.
void log(string message, string level = "INFO") { // ...}
// You can call it with or without the levellog("Server started"); // level becomes "INFO"log("Error", "ERROR"); // level becomes "ERROR"Varargs
Section titled “Varargs”A function can accept a variable number of arguments by adding ... before the type and [] after the name.
int sum(int ...values[]) { int total = 0; for (int i = 0; i < values.length(); i++) { total = total + values[i]; } return total;}// Call: sum(1, 2, 3, 4)Unified Function Call Syntax (UFCS)
Section titled “Unified Function Call Syntax (UFCS)”NSL allows you to call any function as if it were a method of its first argument.
variable.method(args...) <---> method(variable, args...)These are identical:
int len1 = calculateLength(myString);int len2 = myString.calculateLength(); // UFCSThis lets you chain operations beautifully: myString.trim().upper().split(",") instead of split(upper(trim(myString)), ",").
The main Function
Section titled “The main Function”Every script must have a main function. This is where execution starts.
The arguments to main define your script’s input schema. If your script is run via an API, those arguments represent the required JSON payload.
type Config { int retries; string url; }main(Config config, boolean verbose = false) { ... }Running via CLI:
- You can pass these arguments via the
-aor--argflag:nox run script.nox -a config='{"retries": 3, "url": "..."}' - If you don’t provide a required argument, the CLI will interactively ask you for it! For structs, it recursively asks field-by-field.
Control Flow
Section titled “Control Flow”if / else
Section titled “if / else”if (score > 90) { // ...} else if (score > 80) { // ...} else { // ...}NSL supports while, for, and foreach.
// foreach is great for arraysstring[] names = ["Alice", "Bob"];foreach (string n in names) { yield `Hello ${n}`;}Error Handling: try / catch
Section titled “Error Handling: try / catch”You can gracefully catch errors using try / catch.
try { json data = Http.getJson(url);} catch (err) { // err is a string containing the error message yield `Failed to fetch: ${err}`;}CRITICAL NOTE: A catch-all block (catch (err)) does not catch Resource Exceptions (like out of memory, timeout, instruction limit exceeded, or stack overflow). These exceptions cannot be bypassed because they have a kill instruction in their specific catch block that instantly terminates the VM to protect the host.
Yield vs. Return
Section titled “Yield vs. Return”yield value;: Sends an intermediate result to the Host. The script continues running. Use this for progress bars, streaming logs, or returning chunks of data.return value;: Insidemain(), this sends the final result and terminates the Sandbox. Inside a normal function, it just returns a value to the caller.