# Imports and Modules

OxigenLang has a module system that lets you organize code across files and use the standard library. The `introduce` keyword (or its shorthand `intro`) brings modules into scope.

## Standard Library Imports

Use a bare module name to import from the standard library:

```oxi
introduce math
println(math.sqrt(16))
println(math.abs(-5))
```

This creates a **namespace** — you access the module's functions through the module name with dot notation.

## Selective Imports

To import specific functions directly into your scope, use curly braces and `from`:

```oxi
introduce {sqrt, abs} from math
println(sqrt(16))
println(abs(-5))
```

Selective imports don't require the module prefix.

## Local File Imports

Use a dot prefix to import from local `.oxi` files relative to the current file:

```oxi
// Import from ./helpers.oxi (same directory)
introduce .helpers
helpers.my_function()

// Selective import from local file
introduce {my_function} from .helpers
my_function()

// Import from ../utils/format.oxi (parent directory)
introduce ..utils.format
```

- `.` means the current file's directory
- `..` means one directory up
- Additional dots go further up (e.g., `...` = two directories up)
- Dots between names are path separators

## The `intro` Shorthand

`intro` is an alias for `introduce` — they are identical:

```oxi
intro math
intro {split, join} from strings
intro .helpers
```

## Module Behavior

### Namespacing

Whole-module imports create a namespace object. You access members with dot notation:

```oxi
introduce math
introduce strings

println(math.pow(2, 10))
println(strings.upper("hello"))
```

### Exports

Top-level bindings (functions, variables, structs, and patterns) are exported by default — public unless you say otherwise. There is no export list; the exception is marked at the declaration with `hide`.

Use top-level definitions for reusable module APIs, and put script-only work inside `main`. The `main` block is skipped when the file is imported with `introduce`.

### `hide` — module-private functions

A top-level `fun` marked `hide` stays callable inside its own file and is refused across the module boundary:

```oxi
// text.oxi
hide fun __normalize(s <str>) { strings.trim(strings.lower(s)) }

fun matches(a <str>, b <str>) { __normalize(a) == __normalize(b) }
```

```oxi
introduce .text

text.matches(" Ada ", "ada")   // True — the public face
text.__normalize(" Ada ")      // error: '__normalize' is hidden inside module './text'
```

Both routes in are closed, and the error names the reason rather than pretending the function does not exist:

```oxi
introduce {__normalize} from .text
// error: '__normalize' is hidden inside module './text'
//   hint: it is declared `hide fun` and cannot be imported
```

`hide` applies to top-level functions only — `hide x <int> = 1` is a parse error. For struct fields, `hide` goes inside the struct body; see [structs.md](https://www.oxigenlang.org/docs/structs/#hidden-fields).

The stdlib uses it: `array.oxi` marks `_min_index_by` and `_remove_at` hidden, since they are the selection sort behind `sort_by` rather than part of the module's API.

```oxi
// mylib.oxi
fun greet(name) { "Hello, {name}!" }
PI := 3.14159
```

```oxi
// main.oxi
introduce .mylib

main {
    println(mylib.greet("World"))
    println(mylib.PI)
}
```

### Module Caching

Each module file is evaluated only once. If multiple files import the same module, they share the same module object. This means module-level state is shared.

### Circular Import Detection

If file A imports file B which imports file A, OxigenLang will produce a clear error:

```
Error: circular import detected: /path/to/file.oxi
```

Restructure your code to avoid circular dependencies.

## Standard Library Modules

OxigenLang ships with the following standard library modules:

| Module     | Description                                          |
|------------|------------------------------------------------------|
| [`math`](https://www.oxigenlang.org/docs/stdlib/math/) | Math functions (abs, sqrt, pow, floor, ceil, etc.)   |
| [`strings`](https://www.oxigenlang.org/docs/stdlib/strings/) | String manipulation (split, join, trim, upper, etc.) |
| [`array`](https://www.oxigenlang.org/docs/stdlib/array/) | Array operations (map, filter, reduce, sort, etc.)   |
| [`sets`](https://www.oxigenlang.org/docs/stdlib/sets/)   | Set algebra (union, intersection, difference, etc.)  |
| [`io`](https://www.oxigenlang.org/docs/stdlib/io/) | File I/O (read_file, write_file, etc.)               |
| [`os`](https://www.oxigenlang.org/docs/stdlib/os/) | OS interaction (exec, env vars, directories, etc.)   |
| [`path`](https://www.oxigenlang.org/docs/stdlib/path/) | File path manipulation and containment checks        |
| [`time`](https://www.oxigenlang.org/docs/stdlib/time/) | Timestamps, sleep, elapsed time measurement          |
| [`datetime`](https://www.oxigenlang.org/docs/stdlib/datetime/) | UTC calendar dates: format, parse, components |
| [`random`](https://www.oxigenlang.org/docs/stdlib/random/) | Random number generation                             |
| [`regex`](https://www.oxigenlang.org/docs/stdlib/regex/) | Regular expressions (Rust regex syntax)              |
| [`json`](https://www.oxigenlang.org/docs/stdlib/json/) | JSON parsing, serialization, dotted-path access, and merging |
| [`toml`](https://www.oxigenlang.org/docs/stdlib/toml/) | TOML parsing, serialization, dotted-path access, and merging |
| [`encoding`](https://www.oxigenlang.org/docs/stdlib/encoding/) | Base64, hex, and URL percent-encoding          |
| [`hash`](https://www.oxigenlang.org/docs/stdlib/hash/) | SHA-256, SHA-1, MD5 hex digests                      |
| [`net`](https://www.oxigenlang.org/docs/stdlib/net/) | HTTP client, streaming HTTP, TCP and UDP sockets     |
| [`api`](https://www.oxigenlang.org/docs/stdlib/api/) | HTTP server: routing, JSON responses, accept loop    |
| [`result`](https://www.oxigenlang.org/docs/stdlib/result/) | Helpers for the `Error \|\| Value` system      |
| [`test`](https://www.oxigenlang.org/docs/stdlib/test/) | `expect(...)` matchers used by `oxigen test`         |
| [`ansi`](https://www.oxigenlang.org/docs/stdlib/ansi/) | Terminal colour, modifiers, cursor control           |
| [`env`](https://www.oxigenlang.org/docs/stdlib/env/) | Load a `.env` file into a map                        |
| [`parse_args`](https://www.oxigenlang.org/docs/stdlib/parse-args/) | Command-line flag parsing                |

See the [Standard Library Reference](https://www.oxigenlang.org/docs/stdlib/) for full details on each
module.

## Examples

### Using multiple modules together

```oxi
introduce json
introduce net
introduce io

// Fetch JSON from an API
resp := net.get("https://api.example.com/data")
data := json.parse(resp["body"])

// Save to file
io.write_file("data.json", json.stringify(data))
```

### Building a utility with local imports

```oxi
// utils/format.oxi
fun pad_left(s, width, ch) {
    result := s
    repeat when len(result) < width {
        result := str(ch) + result
    }
    result
}
```

```oxi
// main.oxi
introduce .utils.format

main {
    println(format.pad_left("42", 5, "0"))
}
```
