## Modules

Passerine's module system allows large codebases to be broken out into indiviual reusable components. A module is a scopes turned into a struct, and isn't necessarily tied to the file system.

Modules are defined using the `mod`

keyword, which must be followed by a block `{ ... }`

. Here's a simple module that defines some math utilities:

```
circle = mod {
PI = 3.14159265358979
area = r -> r * r * PI
circum = r -> r * PI * 2
}
pizza_radius = 12
slices = 8
slice_area = (circle::area pizza_radius) / slices
```

`mod`

takes all top-level declarations in a block - in this case, `PI`

, `area`

, and `circum`

- and turns them into a struct with those fields. In essence, the above is equivalent to this struct:

```
circle = {
PI: 3.14159265358979
area: r -> r * r * PI
circum: r -> r * PI * 2
}
```

`mod`

is nice because it's an easy way to have multiple returns. In essesence, the `mod`

keyword allows for first-class scoping, by turning scopes into structs:

```
index = numbers pos
-> floor (len numbers * pos)
quartiles = numbers -> mod {
sorted = (sort numbers)
med = sorted::(index (1/2) sorted)
q1 = sorted::(index (1/4) sorted)
q3 = sorted::(index (3/4) sorted)
}
```

Because we used the `mod`

keyword in the above example, instead of returning a single value from the function, we return a struct containing all values in the fuction:

```
-- calculate statistics
numbers = [1, 2, 3, 4, 5]
stats = quartiles numbers
-- use `q1` and `q3` to calculate the interquartile range of `numbers`
iqr = stats::q3 - stats::q1
print "the IQR of { numbers } is { iqr } "
```

This is really useful for writing functions that return multiple values.

Aside from allowing us to group sets of related values into a single namespace, modules can be defined in different files, then be imported. Here's a module defined in a different file:

```
-- list_util.pn
reduce = f start list -> match list {
[] -> start,
[head, ..tail] -> f (reduce f tail, head)
}
sum = reduce { (a, b) -> a + b } 0
reverse = reduce { (a, b) -> [b.., a]} []
```

This file defines a number of useful list utilities, defined in a traditional recursive style. If we want to use this module in `main.pn`

, we import it using the `use`

keyword:

```
-- main.pn
use list_util
numbers = [1, 1, 2, 3, 5]
print (list_util::sum numbers)
```

Note that the `use`

keyword is essentially the same thing as wrapping the contents of the imported file with the `mod`

keyword:

```
-- use list_util
list_util = mod { <list_util.pn> }
```

Once imported, `list_util`

is just a struct. Because of this, features of the module system naturally arise from Passerine's existing semantics for manipulating structs. To import a subset of a module, we can do something like this:

```
reverse = { use list_util; list_util::reduce }
```

Likewise, we can import a module within a block scope to rename it:

```
list_stuff = { use list_util; list_util }
```

There are a number of nice properties that arise from this module system, we've just scratched the surface. As modules are just structs, the full power of passerine and its macro system are at your disposal for building extensible systems that compose well.