From 92d06b1618873faccda40dca00f4d5e9201d42a1 Mon Sep 17 00:00:00 2001 From: walonCode Date: Fri, 26 Jun 2026 06:48:40 +0000 Subject: [PATCH 1/5] docs: add Hello World section to getting started page --- docs/app/docs/page.tsx | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/docs/app/docs/page.tsx b/docs/app/docs/page.tsx index 3418001..d336a07 100644 --- a/docs/app/docs/page.tsx +++ b/docs/app/docs/page.tsx @@ -28,6 +28,21 @@ cargo build --release`} formatter (code-lang-fmt) and language server (code-lang-lsp).

+

Hello, World!

+

+ The smallest possible code-lang program. Create a file called hello.cl: +

+
{`import "fmt";
+
+fmt.print("Hello, World!");`}
+

Run it:

+
{`code-lang hello.cl`}
+
{`Hello, World!`}
+

+ fmt is the standard output module. fmt.print writes to stdout with a newline. + All stdlib modules are built in — just import and use. +

+

The REPL

Run code-lang with no arguments to start the interactive shell. History is saved across sessions. @@ -42,9 +57,9 @@ integer >> exit`}

Exit with exit, exit(), or Ctrl-C.

-

Your first script

+

A longer script

- Scripts use the .cl extension. Create hello.cl: + Scripts use the .cl extension. Here is a program that uses structs, functions, and the math module:

{`import "fmt";
 import "math";
@@ -53,9 +68,9 @@ struct Point {
     x: 0,
     y: 0,
     distance: fn(self) {
-        math.sqrt(self.x ** 2 + self.y ** 2)
+        math.sqrt(self.x ** 2 + self.y ** 2);
     },
-}
+};
 
 let greet = fn(name, msg = "Hello") {
     fmt.print(msg + ", " + name + "!");

From 80fd249df0e876752ddc1496d3b11c96f8bdbbf7 Mon Sep 17 00:00:00 2001
From: walonCode 
Date: Fri, 26 Jun 2026 06:50:47 +0000
Subject: [PATCH 2/5] docs(stdlib): add Returns column to all module reference
 tables

---
 docs/app/docs/stdlib/page.tsx | 261 ++++++++++++++++++----------------
 1 file changed, 137 insertions(+), 124 deletions(-)

diff --git a/docs/app/docs/stdlib/page.tsx b/docs/app/docs/stdlib/page.tsx
index c863ecf..9f50a58 100644
--- a/docs/app/docs/stdlib/page.tsx
+++ b/docs/app/docs/stdlib/page.tsx
@@ -3,197 +3,208 @@ import Pre from "../../components/Pre";
 
 export const metadata: Metadata = { title: "Standard library" };
 
-const MODULES = [
+const MODULES: {
+  name: string;
+  desc: string;
+  fns: [string, string, string][];
+}[] = [
   {
     name: "fmt",
     desc: "Output, input, and type conversion.",
     fns: [
-      ["print(...args)", "Print args space-separated to stdout with newline."],
-      ["eprint(...args)", "Same as print but to stderr."],
-      ["input(prompt)", "Print prompt and read a line from stdin. Returns STRING."],
-      ["typeof(x)", "Return the type name of x as a STRING."],
-      ["to_int(x)", "Convert STRING, FLOAT, or BOOL to INTEGER."],
-      ["to_float(x)", "Convert STRING or INTEGER to FLOAT."],
-      ["to_str(x)", "Convert any value to its STRING representation."],
-      ["clear()", "Clear the terminal screen."],
-      ["format(template, ...args)", "Printf-style formatting: %s string, %d integer, %f float, %% literal percent."],
+      ["print(...args)", "Print args space-separated to stdout with a trailing newline.", "null"],
+      ["eprint(...args)", "Same as print but writes to stderr.", "null"],
+      ["input(prompt)", "Print prompt and read a line from stdin.", "string"],
+      ["to_int(x)", "Convert string, float, or bool to integer.", "integer"],
+      ["to_float(x)", "Convert string or integer to float.", "float"],
+      ["to_str(x)", "Convert any value to its string representation.", "string"],
+      ["format(template, ...args)", "Printf-style formatting: %s string, %d integer, %f float, %% literal percent.", "string"],
+      ["clear()", "Clear the terminal screen.", "null"],
     ],
   },
   {
     name: "math",
     desc: "Mathematical functions and constants.",
     fns: [
-      ["PI", "3.141592… (constant)"],
-      ["E", "2.718281… (constant)"],
-      ["sqrt(n)", "Square root."],
-      ["abs(n)", "Absolute value. Returns same type as input."],
-      ["pow(base, exp)", "base raised to exp. Returns FLOAT."],
-      ["floor(n) / ceil(n) / round(n) / trunc(n)", "Rounding variants."],
-      ["log(n)", "Natural logarithm (ln)."],
-      ["log10(n)", "Base-10 logarithm."],
-      ["log2(n)", "Base-2 logarithm."],
-      ["exp(n)", "e raised to n."],
-      ["sin(n) / cos(n) / tan(n)", "Trigonometric functions (radians)."],
-      ["min(a, b, …) / max(a, b, …)", "Minimum / maximum of one or more numbers."],
-      ["clamp(x, lo, hi)", "Clamp x to the range [lo, hi]."],
-      ["sign(n)", "Returns -1, 0, or 1 based on the sign of n."],
-      ["gcd(a, b)", "Greatest common divisor (integers)."],
-      ["lcm(a, b)", "Least common multiple (integers)."],
+      ["PI", "3.141592… (constant, not a function)", "float"],
+      ["E", "2.718281… (constant, not a function)", "float"],
+      ["sqrt(n)", "Square root of n.", "float"],
+      ["abs(n)", "Absolute value — preserves input type.", "integer or float"],
+      ["pow(base, exp)", "base raised to exp.", "float"],
+      ["floor(n)", "Round down to nearest integer.", "integer"],
+      ["ceil(n)", "Round up to nearest integer.", "integer"],
+      ["round(n)", "Round to nearest integer.", "integer"],
+      ["trunc(n)", "Truncate decimal part toward zero.", "integer"],
+      ["log(n)", "Natural logarithm (ln).", "float"],
+      ["log10(n)", "Base-10 logarithm.", "float"],
+      ["log2(n)", "Base-2 logarithm.", "float"],
+      ["exp(n)", "e raised to n.", "float"],
+      ["sin(n) / cos(n) / tan(n)", "Trigonometric functions — input in radians.", "float"],
+      ["min(a, b) / max(a, b)", "Minimum or maximum of two numbers.", "integer or float"],
+      ["clamp(x, lo, hi)", "Clamp x to the range [lo, hi].", "integer or float"],
+      ["sign(n)", "Returns -1, 0, or 1 based on the sign of n.", "integer"],
+      ["gcd(a, b)", "Greatest common divisor.", "integer"],
+      ["lcm(a, b)", "Least common multiple.", "integer"],
     ],
   },
   {
     name: "strings",
     desc: "String manipulation.",
     fns: [
-      ["to_upper(s) / to_lower(s)", "Case conversion."],
-      ["trim(s) / trim_left(s) / trim_right(s)", "Remove whitespace."],
-      ["split(s, sep)", "Split string into ARRAY of strings."],
-      ["join(arr, sep)", "Join array into a string."],
-      ["contains(s, sub)", "BOOL — whether s contains sub."],
-      ["starts_with(s, prefix) / ends_with(s, suffix)", "BOOL prefix/suffix check."],
-      ["replace(s, old, new)", "Replace all occurrences of old with new."],
-      ["index(s, sub)", "First index of sub in s, or -1."],
-      ["count(s, sub)", "Number of non-overlapping occurrences of sub."],
-      ["repeat(s, n)", "Repeat s n times."],
-      ["reverse(s)", "Reverse the string."],
-      ["to_chars(s)", "ARRAY of CHAR values."],
-      ["from_chars(arr)", "Build a STRING from an array of CHARs."],
-      ["parse_int(s) / parse_float(s)", "Parse string to number."],
-      ["lines(s)", "Split by newline into ARRAY of strings."],
-      ["is_empty(s)", "BOOL — true if string has zero characters."],
-      ["pad_left(s, n, ch)", "Left-pad s to width n using char ch."],
-      ["pad_right(s, n, ch)", "Right-pad s to width n using char ch."],
+      ["to_upper(s) / to_lower(s)", "Case conversion.", "string"],
+      ["trim(s)", "Remove leading and trailing whitespace.", "string"],
+      ["trim_left(s) / trim_right(s)", "Remove whitespace from one side only.", "string"],
+      ["split(s, sep)", "Split s on sep.", "array"],
+      ["join(arr, sep)", "Join array elements into a string with sep between each.", "string"],
+      ["contains(s, sub)", "Whether s contains sub.", "bool"],
+      ["starts_with(s, prefix) / ends_with(s, suffix)", "Prefix or suffix check.", "bool"],
+      ["replace(s, old, new)", "Replace all occurrences of old with new.", "string"],
+      ["index(s, sub)", "First index of sub in s, or -1 if not found.", "integer"],
+      ["count(s, sub)", "Number of non-overlapping occurrences of sub in s.", "integer"],
+      ["repeat(s, n)", "Repeat s n times.", "string"],
+      ["reverse(s)", "Reverse the characters of s.", "string"],
+      ["len(s)", "Number of characters in s.", "integer"],
+      ["to_chars(s)", "Split s into individual characters.", "array"],
+      ["from_chars(arr)", "Build a string from an array of characters.", "string"],
+      ["parse_int(s)", "Parse s as an integer.", "integer"],
+      ["parse_float(s)", "Parse s as a float.", "float"],
+      ["lines(s)", "Split s by newline.", "array"],
+      ["is_empty(s)", "Whether s has zero characters.", "bool"],
+      ["pad_left(s, n, ch)", "Left-pad s to width n using character ch.", "string"],
+      ["pad_right(s, n, ch)", "Right-pad s to width n using character ch.", "string"],
     ],
   },
   {
     name: "arrays",
     desc: "Array operations. All functions return new arrays — no mutation.",
     fns: [
-      ["len(arr)", "Length of array (also works on STRING)."],
-      ["first(arr) / last(arr)", "First / last element, or null if empty."],
-      ["rest(arr)", "Array without the first element."],
-      ["pop(arr)", "Array without the last element."],
-      ["push(arr, x) / prepend(arr, x)", "Return new array with x appended / prepended."],
-      ["concat(a, b)", "Concatenate two arrays."],
-      ["reverse(arr)", "Return reversed array."],
-      ["slice(arr, start, end)", "Subarray from start (inclusive) to end (exclusive)."],
-      ["contains(arr, x)", "BOOL — whether arr contains x."],
-      ["index_of(arr, x)", "First index of x, or -1."],
-      ["join(arr, sep)", "Join elements into a STRING."],
-      ["sum(arr)", "Sum of numeric elements."],
-      ["min(arr) / max(arr)", "Min / max of numeric array."],
-      ["sort(arr)", "Sorted copy (numbers and strings)."],
-      ["unique(arr)", "Remove duplicates, preserve order."],
-      ["flatten(arr)", "Flatten one level of nesting."],
-      ["zip(a, b)", "Array of [a[i], b[i]] pairs, stops at shorter."],
-      ["map(arr, fn)", "Return new array of fn(element) results."],
-      ["filter(arr, fn)", "Return elements where fn(element) is truthy."],
-      ["reduce(arr, fn, init)", "Accumulate fn(acc, element) left-to-right, starting from init."],
-      ["find(arr, fn)", "First element where fn(element) is truthy, or null."],
-      ["any(arr, fn)", "BOOL — true if any element passes fn."],
-      ["all(arr, fn)", "BOOL — true if all elements pass fn."],
+      ["len(arr)", "Number of elements.", "integer"],
+      ["first(arr) / last(arr)", "First or last element, or null if the array is empty.", "any or null"],
+      ["rest(arr)", "New array without the first element.", "array"],
+      ["pop(arr)", "New array without the last element.", "array"],
+      ["push(arr, x)", "New array with x appended.", "array"],
+      ["prepend(arr, x)", "New array with x prepended.", "array"],
+      ["concat(a, b)", "Concatenate two arrays.", "array"],
+      ["reverse(arr)", "Reversed copy of arr.", "array"],
+      ["slice(arr, start, end)", "Subarray from start (inclusive) to end (exclusive).", "array"],
+      ["contains(arr, x)", "Whether arr contains x.", "bool"],
+      ["index_of(arr, x)", "First index of x, or -1 if not found.", "integer"],
+      ["join(arr, sep)", "Join elements into a string with sep between each.", "string"],
+      ["sum(arr)", "Sum of all numeric elements.", "integer or float"],
+      ["min(arr) / max(arr)", "Minimum or maximum element of a numeric array.", "integer or float"],
+      ["sort(arr)", "Sorted copy — works on numbers and strings.", "array"],
+      ["unique(arr)", "Copy with duplicates removed, order preserved.", "array"],
+      ["flatten(arr)", "Flatten one level of nesting.", "array"],
+      ["zip(a, b)", "Array of [a[i], b[i]] pairs, stops at the shorter array.", "array"],
+      ["map(arr, fn)", "New array of fn(element) results.", "array"],
+      ["filter(arr, fn)", "Elements where fn(element) is truthy.", "array"],
+      ["reduce(arr, fn, init)", "Accumulate fn(acc, element) left-to-right, starting from init.", "any"],
+      ["find(arr, fn)", "First element where fn(element) is truthy, or null.", "any or null"],
+      ["any(arr, fn)", "Whether at least one element passes fn.", "bool"],
+      ["all(arr, fn)", "Whether every element passes fn.", "bool"],
     ],
   },
   {
     name: "hash",
     desc: "Hash (dictionary) operations.",
     fns: [
-      ["keys(h)", "ARRAY of keys."],
-      ["values(h)", "ARRAY of values."],
-      ["entries(h)", "ARRAY of [key, value] pairs."],
-      ["has_key(h, k)", "BOOL — whether key k exists."],
-      ["get(h, k, default)", "Value for key k, or default if key is absent."],
-      ["len(h)", "Number of key-value pairs."],
-      ["merge(h1, h2)", "New hash with both; h2 overwrites h1 on conflicts."],
-      ["delete(h, k)", "New hash without key k."],
+      ["keys(h)", "All keys.", "array"],
+      ["values(h)", "All values.", "array"],
+      ["entries(h)", "All [key, value] pairs.", "array"],
+      ["has_key(h, k)", "Whether key k exists in h.", "bool"],
+      ["get(h, k, default)", "Value for key k, or default if the key is absent.", "any"],
+      ["len(h)", "Number of key-value pairs.", "integer"],
+      ["merge(h1, h2)", "New hash with entries from both; h2 wins on key conflicts.", "hash"],
+      ["delete(h, k)", "New hash without key k.", "hash"],
     ],
   },
   {
     name: "fs",
     desc: "File system I/O.",
     fns: [
-      ["read_file(path)", "Read file contents as STRING."],
-      ["write_file(path, content)", "Write STRING to file (overwrite). Returns BOOL."],
-      ["append_file(path, content)", "Append STRING to file (creates if missing). Returns BOOL."],
-      ["read_lines(path)", "Read file into ARRAY of strings (one per line)."],
-      ["exists(path)", "BOOL — path exists."],
-      ["is_file(path) / is_dir(path)", "BOOL — type check."],
-      ["list_dir(path)", "ARRAY of filenames in directory."],
-      ["mkdir(path) / mkdir_all(path)", "Create directory / all intermediate directories."],
-      ["remove(path)", "Delete a file."],
-      ["remove_dir(path)", "Delete a directory and all its contents."],
-      ["copy(src, dst) / rename(src, dst)", "Copy or rename a file."],
+      ["read_file(path)", "Read file contents as a string.", "string or error"],
+      ["write_file(path, content)", "Write string to file, overwriting if it exists.", "bool"],
+      ["append_file(path, content)", "Append string to file, creating it if missing.", "bool"],
+      ["read_lines(path)", "Read file into an array of strings, one per line.", "array or error"],
+      ["exists(path)", "Whether path exists on disk.", "bool"],
+      ["is_file(path) / is_dir(path)", "Type check — file or directory.", "bool"],
+      ["list_dir(path)", "Filenames inside a directory.", "array or error"],
+      ["mkdir(path)", "Create a directory.", "bool"],
+      ["mkdir_all(path)", "Create a directory and all missing parents.", "bool"],
+      ["remove(path)", "Delete a file.", "bool"],
+      ["remove_dir(path)", "Delete a directory and all its contents.", "bool"],
+      ["copy(src, dst) / rename(src, dst)", "Copy or rename a file.", "bool"],
     ],
   },
   {
     name: "path",
     desc: "Path string manipulation — no filesystem access except absolute().",
     fns: [
-      ["join(a, b, …)", "Join path segments with the OS separator."],
-      ["basename(p)", "Filename with extension."],
-      ["dirname(p)", "Parent directory."],
-      ["stem(p)", "Filename without extension."],
-      ["extension(p)", "Extension without the leading dot."],
-      ["absolute(p)", "Canonicalized absolute path (hits filesystem)."],
-      ["is_absolute(p)", "BOOL — whether path is absolute."],
+      ["join(a, b, …)", "Join path segments with the OS separator.", "string"],
+      ["basename(p)", "Filename with extension.", "string"],
+      ["dirname(p)", "Parent directory.", "string"],
+      ["stem(p)", "Filename without extension.", "string"],
+      ["extension(p)", "Extension without the leading dot.", "string"],
+      ["absolute(p)", "Canonicalized absolute path — hits the filesystem.", "string"],
+      ["is_absolute(p)", "Whether path is absolute.", "bool"],
     ],
   },
   {
     name: "os",
     desc: "Operating system interface.",
     fns: [
-      ["args", "ARRAY of command-line arguments (value, not function)."],
-      ["platform", "OS name string, e.g. \"linux\", \"macos\", \"windows\" (value)."],
-      ["arch", "CPU architecture string (value)."],
-      ["get_env(key)", "Read an environment variable. Returns STRING (empty if unset)."],
-      ["set_env(key, val)", "Set an environment variable."],
-      ["get_wd()", "Current working directory as STRING."],
-      ["hostname()", "Machine hostname as STRING."],
-      ["exit(code?)", "Exit the process with optional integer code (default 0)."],
+      ["args", "Command-line arguments passed to the script (value, not a function).", "array"],
+      ["platform", "OS name — e.g. \"linux\", \"macos\", \"windows\" (value, not a function).", "string"],
+      ["arch", "CPU architecture string (value, not a function).", "string"],
+      ["get_env(key)", "Read an environment variable. Returns empty string if unset.", "string"],
+      ["set_env(key, val)", "Set an environment variable for the current process.", "null"],
+      ["get_wd()", "Current working directory.", "string"],
+      ["hostname()", "Machine hostname.", "string"],
+      ["exit(code?)", "Exit the process. Optional integer exit code, defaults to 0.", "—"],
     ],
   },
   {
     name: "time",
-    desc: "Date and time. Timestamps are unix milliseconds (INTEGER).",
+    desc: "Date and time. All timestamps are unix milliseconds (integer).",
     fns: [
-      ["now()", "Current time as unix milliseconds."],
-      ["unix()", "Current time as unix seconds."],
-      ["sleep(ms)", "Pause execution for ms milliseconds."],
-      ["since(start_ms)", "Milliseconds elapsed since start_ms."],
-      ["format(ms, layout)", "Format timestamp using a strftime-style layout string."],
-      ["year(ms) / month(ms) / day(ms)", "Date components (UTC). Month is 1–12."],
-      ["hour(ms) / minute(ms) / second(ms)", "Time components (UTC)."],
-      ["RFC3339", "\"%Y-%m-%dT%H:%M:%S%z\" layout constant."],
-      ["Kitchen", "\"%I:%M %p\" layout constant."],
+      ["now()", "Current time as unix milliseconds.", "integer"],
+      ["unix()", "Current time as unix seconds.", "integer"],
+      ["sleep(ms)", "Pause execution for ms milliseconds.", "null"],
+      ["since(start_ms)", "Milliseconds elapsed since start_ms.", "integer"],
+      ["format(ms, layout)", "Format a timestamp using a strftime-style layout string.", "string"],
+      ["year(ms) / month(ms) / day(ms)", "Date components (UTC). month() is 1–12.", "integer"],
+      ["hour(ms) / minute(ms) / second(ms)", "Time components (UTC).", "integer"],
+      ["RFC3339", "\"%Y-%m-%dT%H:%M:%S%z\" layout constant (value, not a function).", "string"],
+      ["Kitchen", "\"%I:%M %p\" layout constant (value, not a function).", "string"],
     ],
   },
   {
     name: "json",
     desc: "JSON serialisation.",
     fns: [
-      ["parse(s)", "Parse a JSON string into code-lang values. JSON objects become HASH."],
-      ["stringify(x)", "Serialize a value to a JSON STRING."],
+      ["parse(s)", "Parse a JSON string. JSON objects become hash, arrays become array.", "hash, array, string, integer, float, bool, or null"],
+      ["stringify(x)", "Serialize a value to a JSON string.", "string"],
     ],
   },
   {
     name: "rand",
     desc: "Random number generation.",
     fns: [
-      ["int(min, max)", "Random INTEGER in [min, max] inclusive."],
-      ["float()", "Random FLOAT in [0.0, 1.0)."],
-      ["choice(arr)", "Random element from array."],
-      ["shuffle(arr)", "Return a new shuffled copy of the array (Fisher-Yates)."],
+      ["int(min, max)", "Random integer in [min, max] inclusive.", "integer"],
+      ["float()", "Random float in [0.0, 1.0).", "float"],
+      ["choice(arr)", "Random element from array, or null if the array is empty.", "any or null"],
+      ["shuffle(arr)", "Shuffled copy of the array (Fisher-Yates).", "array"],
     ],
   },
   {
     name: "http",
-    desc: "Blocking HTTP client. All functions return a HASH with status (INTEGER), body (STRING), and ok (BOOL).",
+    desc: "Blocking HTTP client.",
     fns: [
-      ["get(url)", "HTTP GET."],
-      ["get(url, headers)", "HTTP GET with custom headers (HASH of STRING→STRING)."],
-      ["post(url, body)", "HTTP POST with a plain string body."],
-      ["post(url, body, headers)", "HTTP POST with custom headers."],
-      ["post_json(url, obj)", "HTTP POST with JSON body (sets Content-Type automatically)."],
+      ["get(url)", "HTTP GET. Returns a hash with status (integer), body (string), and ok (bool).", "hash"],
+      ["get(url, headers)", "HTTP GET with custom headers (hash of string → string).", "hash"],
+      ["post(url, body)", "HTTP POST with a plain string body.", "hash"],
+      ["post(url, body, headers)", "HTTP POST with custom headers.", "hash"],
+      ["post_json(url, obj)", "HTTP POST with JSON body — sets Content-Type automatically.", "hash"],
     ],
   },
 ];
@@ -222,13 +233,15 @@ strings.to_upper("hello");  # HELLO`}
Function / value Description + Returns - {mod.fns.map(([sig, desc]) => ( + {mod.fns.map(([sig, desc, ret]) => ( {sig} {desc} + {ret} ))} From 68f70a43d64d113bd2d588abe14750f5d15da701 Mon Sep 17 00:00:00 2001 From: walonCode Date: Fri, 26 Jun 2026 06:51:39 +0000 Subject: [PATCH 3/5] docs(language): add default arm to switch examples, improve error handling section --- docs/app/docs/language/page.tsx | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/docs/app/docs/language/page.tsx b/docs/app/docs/language/page.tsx index cc8fc34..f24accb 100644 --- a/docs/app/docs/language/page.tsx +++ b/docs/app/docs/language/page.tsx @@ -182,7 +182,8 @@ for (name, score in scores) {

switch

Compare a subject against a series of patterns using ==. The first matching arm runs. - If no arm matches, the result is null. + Add a default arm to handle any value that does not match. If no arm matches and + there is no default, the result is null.

{`let direction = Direction.North;
 
@@ -191,6 +192,7 @@ switch (direction) {
     Direction.South => fmt.print("going south"),
     Direction.East  => fmt.print("going east"),
     Direction.West  => fmt.print("going west"),
+    default         => fmt.print("unknown direction"),
 };
 
 # switch on any value
@@ -198,6 +200,7 @@ switch (score // 10) {
     10 => "A+",
     9  => "A",
     8  => "B",
+    default => "below B",
 };`}

Functions

@@ -330,23 +333,26 @@ switch (d) {

Error handling

- Errors in code-lang are values. When a stdlib function fails it returns an error object — - it does not crash the program. Use is_error(val) to test it. + Errors in code-lang are values, not exceptions. When a stdlib function fails it returns an + error object — it does not crash the program. Use is_error(val) to check it.

-
{`import "fs";
+      
{`import "fmt";
+import "fs";
 
 let content = fs.read_file("maybe.txt");
 
 if (is_error(content)) {
-    fmt.print("file not found");
+    fmt.print("could not read file");
 } else {
     fmt.print(content);
 };`}
- is_error() is a global builtin — no import needed. Errors stored in let or{" "} - const are recoverable values. A bare error expression (not assigned) propagates and - halts the current block. + is_error() is a global builtin — no import needed. An error value stored in a + variable is safe to inspect. A bare error expression that is not assigned or checked propagates + up and halts the current block. +

Use ?? to supply a fallback when a value is null:

+
{`let val = might_be_null() ?? "default";`}

Modules

From ee4f7ba4855f3aed8fd1e9fc68ad70931f8105a3 Mon Sep 17 00:00:00 2001 From: walonCode Date: Fri, 26 Jun 2026 06:52:20 +0000 Subject: [PATCH 4/5] docs(getting-started): improve module examples and add output comments --- docs/app/docs/page.tsx | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/docs/app/docs/page.tsx b/docs/app/docs/page.tsx index d336a07..b0905c8 100644 --- a/docs/app/docs/page.tsx +++ b/docs/app/docs/page.tsx @@ -88,16 +88,19 @@ distance: 5`}
All standard library modules are built in — no installation or setup needed. Import any module by name and call its functions with dot notation:

-
{`import "strings";
+      
{`import "fmt";
+import "strings";
 import "arrays";
 import "json";
 
-strings.to_upper("hello");                       # HELLO
-arrays.map([1, 2, 3], fn(x) { x * 2 });         # [2, 4, 6]
-arrays.filter([1,2,3,4], fn(x) { x % 2 == 0 }); # [2, 4]
-json.stringify({ "ok": true });                  # {"ok":true}`}
+strings.to_upper("hello"); # HELLO +arrays.map([1, 2, 3], fn(x) { x * 2; }); # [2, 4, 6] +arrays.filter([1, 2, 3, 4], fn(x) { x % 2 == 0; }); # [2, 4] +json.stringify({ "ok": true }); # {"ok":true} + +fmt.print(strings.to_upper("hello")); # HELLO`}

- See the standard library reference for all 12 modules. + See the standard library reference for all 12 modules and their return types.

Language features at a glance

@@ -105,28 +108,35 @@ json.stringify({ "ok": true }); # {"ok":true}`}

null and ??

{`let x;              # uninitialized — defaults to null
-let y = x ?? 0;     # 0, because x is null
-let z = 5 ?? 0;     # 5, because 5 is not null`}
+let y = x ?? 0; # 0 (x is null, so fall back to 0) +let z = 5 ?? 0; # 5 (5 is not null, keep it)`}

Destructuring

{`let [a, b, c] = [1, 2, 3];
-let { name, age } = { "name": "Walon", "age": 25 };`}
+let { name, age } = { "name": "Walon", "age": 25 }; + +fmt.print(a); # 1 +fmt.print(name); # Walon`}

Enums and switch

-
{`enum Status { Ok, Pending, Err }
+      
{`import "fmt";
+
+enum Status { Ok, Pending, Err }
 
 let s = Status.Ok;
 switch (s) {
     Status.Ok      => fmt.print("all good"),
     Status.Pending => fmt.print("waiting"),
     Status.Err     => fmt.print("failed"),
+    default        => fmt.print("unknown"),
 };`}

typeof

-
{`typeof 42;       # "integer"
-typeof "hello";  # "string"
-typeof null;     # "null"
-typeof [1,2];    # "array"`}
+
{`typeof 42;        # "integer"
+typeof "hello";   # "string"
+typeof null;      # "null"
+typeof [1, 2];    # "array"
+typeof true;      # "boolean"`}

Error format

From 3acd7abb777e56fb8ef3bfb91edce88d5aa30136 Mon Sep 17 00:00:00 2001 From: walonCode Date: Fri, 26 Jun 2026 06:52:49 +0000 Subject: [PATCH 5/5] docs(stdlib): improve intro example to show return types and typeof usage --- docs/app/docs/stdlib/page.tsx | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/app/docs/stdlib/page.tsx b/docs/app/docs/stdlib/page.tsx index 9f50a58..aa425ff 100644 --- a/docs/app/docs/stdlib/page.tsx +++ b/docs/app/docs/stdlib/page.tsx @@ -214,13 +214,20 @@ export default function StdlibReference() { <>

Standard library

- All stdlib modules are preloaded — no installation needed. Import a module by name and use dot notation to call its functions. + All 12 stdlib modules are preloaded — no installation needed. Import a module by name and use dot + notation to call its functions. The Returns column shows the type each function + produces. Use typeof at any time to confirm the type of a value at runtime.

-
{`import "math";
+      
{`import "fmt";
+import "math";
 import "strings";
 
-math.sqrt(9);               # 3.0
-strings.to_upper("hello");  # HELLO`}
+math.sqrt(9); # 3.0 → float +strings.to_upper("hello"); # HELLO → string +strings.split("a,b,c", ","); # ["a", "b", "c"] → array + +typeof math.sqrt(9); # "float" +typeof strings.split("a", ","); # "array"`}
{MODULES.map((mod) => (