

# Standard library

Silk’s standard library lives under the reserved `std::` namespace. This is where “practical systems programming” shows up:
I/O, filesystem, networking, parsing, collections, time, and the shared conventions that make those modules compose.

This page is not a full reference (the sidebar is). It’s a guide to the **shape** of `std::`, how to use it, and what
patterns to expect.

## Importing `std::` modules

Use module-specifier imports for application and library code:

```silk
import io from "std/io";              // namespace import; call io::println(...)
import { println } from "std/io";     // selected symbol import
import fs from "std/fs";              // filesystem namespace
```

Use selected imports when a small program needs one or two names. Use namespace
imports when a module uses a cohesive surface such as `fs::read_file_string`.
Direct imports such as `import std::io::println;` remain available for ABI-facing
definition modules and low-level interop code; ordinary user-space code should
prefer `from "std/..."`.

Some standard-library types are always in scope through the std prelude. `Result`
is one of those globals, so user code writes `Result(T, E)` without importing
[`std/result`](https://github.com/oro-computer/silk/tree/master/std/result).

## The three common “return shapes”

`std::` APIs intentionally reuse a small set of patterns so code stays readable.

### 1) Optionals: `T?`

`T?` means “a `T` or no value” (`Some(...)` / `None`).

Use this when “absence” is expected and you don’t need rich error information.

```silk
fn parse_port (s: string) -> int? {
  // Example sketch: a real parser would validate digits.
  if s == "" { return None; }
  return Some(8080);
}
```

### 2) Results: `Result(T, E)`

`Result(T, E)` is the standard “success or error” type used across `std::`.

```silk
type IntOrMessage = Result(int, string);

fn div (a: int, b: int) -> IntOrMessage {
  if b == 0 { return Err("division by zero"); }
  return Ok(a / b);
}
```

In real code you typically [`match`](/silk/wiki/language/flow-match/) on a result so success and failure paths stay explicit.

### 3) Typed errors: `T | E`

Silk supports typed errors directly in the language: a value is either a success type `T` or an error type `E`.

This is a good fit when:

- the error has structure (fields), and
- callers are expected to handle distinct failure reasons.

You’ll see both `T | E` and `Result(T, E)` in the ecosystem; `std::` uses `Result` heavily because it composes cleanly and
is easy to pattern-match.

## A quick tour of key modules

### [`std::io`](/silk/docs/std/io/) — printing and stream I/O

[`std::io`](/silk/docs/std/io/) covers console I/O and basic stream patterns.

```silk
import { println } from "std/io";

fn main () -> int {
  println("hello {s} answer={d}", "world", 42);
  return 0;
}
```

When you need lower-level I/O, [`std::io`](/silk/docs/std/io/) also exposes byte-oriented read/write primitives and stable error kinds.

Reference: [`std::io`](/silk/docs/std/io/) (see the sidebar under “Standard library”).

### [`std::fs`](/silk/docs/std/fs/) — filesystem operations

[`std::fs`](/silk/docs/std/fs/) provides file and directory helpers and a low-level `File` handle.

Whole-file helpers are intentionally common:

```silk
import fs from "std/fs";
import { println } from "std/io";

fn main () -> int {
  match (fs::read_file_string("message.txt")) {
    Ok(s) => {
      println("{s}", s.as_string());
      return 0;
    },
    Err(e) => {
      // A real program would format/inspect `e.kind()` and report it.
      println("read failed");
      return 1;
    },
  }
}
```

Reference: [`std::fs`](/silk/docs/std/fs/), [`std::path`](/silk/docs/std/path/).

### [`std::strings`](/silk/docs/std/strings/) — owned strings and utilities

Silk has a built-in `string` type (an immutable view over UTF‑8 bytes). The standard library adds an owning `String` for
when you need to build or retain dynamic strings.

Reference: [`std::strings`](/silk/docs/std/strings/), [`std::unicode`](/silk/docs/std/unicode/).

### [`std::json`](/silk/docs/std/json/) and [`std::toml`](/silk/docs/std/toml/) — configuration and structured data

Silk includes parsers for data formats used in real programs:

- [`std::toml`](/silk/docs/std/toml/) for configuration (including `silk.toml` manifests)
- [`std::json`](/silk/docs/std/json/) for interoperability and structured data exchange
- [`std::mime`](/silk/docs/std/mime/) for file-extension and content-type lookups in static servers,
 package publication helpers, and indexing tools

Reference: [`std::toml`](/silk/docs/std/toml/), [`std::json`](/silk/docs/std/json/), [`std::mime`](/silk/docs/std/mime/).

### [`std::task`](/silk/docs/std/task/), [`std::sync`](/silk/docs/std/sync/), [`std::temporal`](/silk/docs/std/temporal/)

For concurrent and time-aware programs, `std::` provides:

- [`std::task`](/silk/docs/std/task/) (tasks, scheduling primitives)
- [`std::sync`](/silk/docs/std/sync/) (mutexes/locks and synchronization)
- [`std::temporal`](/silk/docs/std/temporal/) (time types like `Duration`/`Instant`)

Reference: [`std::task`](/silk/docs/std/task/), [`std::sync`](/silk/docs/std/sync/), [`std::temporal`](/silk/docs/std/temporal/).

### [`std::gpu`](/silk/docs/std/gpu/) — portable device execution

[`std::gpu`](/silk/docs/std/gpu/) provides runtime discovery, device selection, buffers, transfers,
streams, launch, and synchronization for mixed CPU/GPU executables. Portable
device functions use [`std::gpu::device`](/silk/docs/std/gpu-device/) operations and the same source can
target the documented AMD/HIP and NVIDIA/CUDA providers.

Use the checked `gpu (...) { ... }` form when launch and synchronization should
remain one typed operation. Use the separate manual APIs when GPU work must
overlap with host work.

Reference: [`std::gpu`](/silk/docs/std/gpu/), [`std::gpu::device`](/silk/docs/std/gpu-device/),
[GPU launch blocks](/silk/docs/language/gpu-launch-blocks/), and [Pure-Silk CPU/GPU
program](/silk/docs/usage/pure-silk-gpu/).

## How to keep `std::` code readable

Two patterns pay off quickly:

1. **Use small local aliases for verbose types.** For example, alias a `Result` instantiation to a short name.
2. **Prefer [`match`](/silk/wiki/language/flow-match/) at boundaries.** Convert errors into your own types at module boundaries, so the rest of your program
 doesn’t become a chain of “plumbing”.

## Next

- [CLI and toolchain](/silk/docs/guides/cli/)
- [Testing](/silk/docs/guides/testing/)
