# Tour

Gizlang is a language with the syntax of TypeScript that compiles to native code, and a toolchain with libraries for
the work around it. One install gives all of the parts below. Each program here is a file in
[`examples/tour`](https://github.com/gizai/gizlang/tree/main/examples/tour), and a test runs each one, so the output
that you see is what it prints. Run one with `giz FILE`.

| Part | Import | What it gives |
| --- | --- | --- |
| [The language](#the-language) | | Types, records, unions, `match`, `Result`, contracts, generics, markup |
| [The standard library](#tasks) | `gizlang:NAME` | System, files, text, collections, JSON, HTTP, crypto, tasks, time, tests |
| [GizDB](#gizdb) | `gizdb` | A SQL database in the program, or a PostgreSQL-protocol server |
| [GizWeb](#gizweb) | `gizweb` | Server-rendered web apps from pages, models and actions |
| [Compute](#compute) | `gizml` | Tensors on the CPU and GPU, gradients, GPU kernels, models |
| [Storage](#storage) | `gizfs` | Buckets and objects, embedded or on a range of machines |
| [Devices](#devices) | `gizhw` | GPUs, NPUs, cameras, audio, sensors and other devices |
| [AI models](#ai-models) | `gizml:ai` | Chat, images and the OpenAI API by model name, on your machine |
| [JavaScript and Python](#javascript-and-python) | | `.js`, `.ts` and `.py` programs on the Gizlang VM |

## The language

Types are checked when you compile. A union names its cases, and `match` must cover each one. `try` returns the error
of a failed step.

```gizlang run file="examples/tour/hello.giz"
// The language: records, unions, match, Result and try. TypeScript syntax, native code.
type Shape = | { kind: "circle"; r: f64; } | { kind: "square"; side: f64; };

function area(s: Shape): f64 {
    match (s) {
        Shape.circle(r) => { return 3.14159 * r * r; }
        Shape.square(side) => { return side * side; }
    }
}

function half(n: i64): Result<i64, string> {
    if (n % 2 !== 0) { return Result.err(`${n} is odd`); }
    return Result.ok(n / 2);
}

function quarter(n: i64): Result<i64, string> { return half(try half(n)); }

function main(): void {
    const shapes: Vec<Shape> = [Shape.circle(1.0), Shape.square(2.0)];
    for (const s of shapes) { print(`area ${area(s)}`); }
    for (const n of [12, 6]) {
        match (quarter(n)) {
            Result.ok(q) => { print(`${n} / 4 = ${q}`); }
            Result.err(why) => { print(`${n}: ${why}`); }
        }
    }
}
```

```text output
area 3.14159
area 4
12 / 4 = 3
6: 3 is odd
```

Next: [the language guide](guides/language.md), and [the differences from TypeScript](reference/typescript.md).

## Tasks

`Task.parallel` runs a body on each core, and gives the results in index order. The standard library (`gizlang:`)
also has threads, channels, timers and async I/O.

```gizlang run file="examples/tour/tasks.giz"
// Tasks: Task.parallel runs a body on every core and gives the results in order.
import * as Task from "gizlang:task";

function main(): void {
    const squares = Task.parallel(8, (i: i64): i64 => { return i * i; });
    let sum = 0;
    for (const s of squares) { sum += s; }
    print(`${squares.map((s: i64): string => { return string(s); }).join(" ")} sum ${sum}`);
}
```

```text output
0 1 4 9 16 25 36 49 sum 140
```

Next: [the standard library reference](reference/sdk.md).

## GizDB

GizDB is a database in your program: a folder, SQL with parameters, transactions, and no server to run. The same
engine is also a server that PostgreSQL clients use.

```gizlang file="examples/tour/data.giz"
// GizDB in the program: a database in a folder, SQL with parameters, no server.
import {System} from "gizlang:system";
import * as Store from "gizdb:store";

function main(sys: System): void {
    const folder = sys.temporaryDir()!;
    const db = Store.open(sys, folder.temporaryPath()!).unwrap();
    db.exec("CREATE TABLE notes (id INT PRIMARY KEY, title TEXT, stars INT)").unwrap();
    db.query("INSERT INTO notes VALUES ($1, $2, $3)", ["1", "Buy milk", "2"]).unwrap();
    db.query("INSERT INTO notes VALUES ($1, $2, $3)", ["2", "Write the tour", "5"]).unwrap();
    for (const row of db.query("SELECT title, stars FROM notes WHERE stars > $1", ["3"]).unwrap().rows) {
        print(`${row[0]!} ${row[1]!}`);
    }
    db.close();
}
```

```text output
Write the tour 5
```

Next: [use GizDB](guides/data.md), [model your data](guides/model.md), [vector search](guides/vector.md),
[machine learning in SQL](guides/sql-ml.md), [run the GizDB server](operations/gizdb-server.md).

## GizWeb

A GizWeb site can be a folder of pages: each `.ghtml`, `.md` and `.html` file under `pages/` is an address. A `.ghtml`
file is HTML with Gizlang in braces. This is `examples/web/pages`:

```gizlang file="examples/web/pages/main.giz"
// A site from files, like PHP or Next.js: every .ghtml, .md and .html file of pages/ is an address (docs/reference/ghtml.md).
// Run: giz examples/web/pages/main.giz, then open http://127.0.0.1:8080
import {System} from "gizlang:system";
import * as Web from "gizweb";
import * as Pages from "gizweb:pages";
import {site} from "./pages/.routes";

function main(sys: System): i64 {
    return Web.listen(
        sys,
        8080,
        Pages.shell(""),
        Web.serving(),
        (own: System) => Pages.handler(site(), Pages.shell(""), Pages.standalone(own))
    );
}
```

```html file="examples/web/pages/pages/blog/[slug].ghtml"
<script>
    const slug = params.get("slug");
</script>
<article>
  <h1>Post: {slug}</h1>
  <p><a href="/blog">All posts</a></p>
</article>
```

`giz examples/web/pages/main.giz` serves it at `http://127.0.0.1:8080`, and `/blog/hello` shows "Post: hello".

Next: [build a web app](guides/web.md), where one model gives the table, the form, the checks and the API.

## Compute

`gizml` has tensors, fused elementwise chains, gradients and models. The same calls run on a GPU when the machine has
one.

```gizlang run file="examples/tour/tensors.giz"
// gizml: tensors on the CPU, or on a GPU when the machine has one.
import * as T from "gizml:tensor";

function main(): void {
    const a = T.tensor([2, 3], [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
    const b = T.tensor([3, 2], [1.0, 0.0, 0.0, 1.0, 1.0, 1.0]);
    print(a.matmul(b).text());
}
```

```text output
[[4, 5], [10, 11]]
```

Next: [tensors, GPU kernels and gradients](guides/compute.md).

## Storage

`gizfs` keeps buckets and objects. Here it is embedded in the program; the same calls reach a range of machines or
gizstack.com.

```gizlang file="examples/tour/storage.giz"
// gizfs: buckets and objects, here in an embedded store in a folder.
import {System} from "gizlang:system";
import {embedded} from "gizfs:node";
import * as Object from "gizfs:object";

function main(sys: System): void {
    const folder = sys.temporaryDir()!;
    const store = embedded(sys, folder.temporaryPath()!, "me").unwrap();
    store.changeObject(Object.Command.bucket("me", "photos", false)).unwrap();
    store.put("photos", "2026/hello.txt", utf8("Hello"), "text/plain").unwrap();
    print(string(store.get("photos", "2026/hello.txt", 0).unwrap()));
    store.close();
}
```

```text output
Hello
```

Next: [use storage](guides/storage.md), [run a storage range](operations/storage-range.md).

## Devices

`gizhw` reads and drives the machine: GPUs, NPUs, cameras, audio, video codecs and sensors. This program prints the
platform and each sensor that the operating system shows, so its output is that of your machine.

```gizlang file="examples/tour/devices.giz"
// gizhw: the machine's devices and sensors, read from the operating system.
import {System} from "gizlang:system";
import * as Device from "gizhw:device";

function main(sys: System): void {
    print(Device.platform(sys));
    for (const s of Device.sensors(sys).valueOr([])) { print(`${s.device} ${s.channel} ${s.value}`); }
}
```

Next: [compute on the GPU](guides/compute.md#step-2-the-same-work-on-a-gpu).

## AI models

`gizml:ai` runs models by name on your machine: chat, embeddings and images, and an OpenAI-compatible server. The
first use downloads the weights.

```sh
giz ai chat qwen3.5-4b "Name three rivers."
```

Next: [run AI models](guides/ai.md).

## JavaScript and Python

The `giz` command also runs JavaScript, TypeScript and Python on the Gizlang VM, with npm packages, Node's modules and
Python's standard library.

```typescript file="examples/tour/hello.ts"
// TypeScript on the Gizlang VM: Node's modules work, with no Node.js installed.
import { createHash } from "node:crypto";

const words: string[] = "the cat and the dog".split(" ");
const counts = new Map<string, number>();
for (const w of words) counts.set(w, (counts.get(w) ?? 0) + 1);
console.log([...counts].map(([w, n]) => `${w}=${n}`).join(" "));
console.log(createHash("sha256").update("gizlang").digest("hex").slice(0, 16));
```

```text output
the=2 cat=1 and=1 dog=1
db69adfa269a71dd
```

```python file="examples/tour/hello.py"
# Python on the Gizlang VM: the program runs in the VM's interpreter and JIT.
import json

counts = {}
for word in "the cat and the dog".split():
    counts[word] = counts.get(word, 0) + 1
print(json.dumps(counts, sort_keys=True))
```

```text output
{"and": 1, "cat": 1, "dog": 1, "the": 2}
```

Next: [JavaScript, TypeScript and Python](guides/javascript-python.md).

## More programs

| Program | Shows |
| --- | --- |
| `examples/cli/wordcount.giz` | A command-line tool: files, `Result` and `try`, maps and the exit code |
| `examples/cli/orders.giz` | One record type gives the DDL, the form checks, the rows and the JSON ([model your data](guides/model.md)) |
| `examples/web/http` | A server-rendered app on `gizlang:http` alone: routes, markup components and a form |
| `examples/web/notes` | The same app on GizWeb, with unit tests and a journey test ([build a web app](guides/web.md)) |
| `examples/web/admin` | An admin app from one annotated record type, with no page or action written |
