# Modules and mixins

> Organize static functions and reusable behavior with modules, include, extend, Enumerable, and Comparable.

Canonical: https://alice-lang.org/documentation/language/modules/

[Documentation index](https://alice-lang.org/documentation/llms.txt) · [Complete book](https://alice-lang.org/llms-full.txt)

## Two kinds of module method

A module can contain static functions or mixin templates. `def self.f` defines a function called as `Module.f`. `def f` defines behavior that is rebound into a receiving class with `include` or `extend`.

```alice
module Greeter
  def greet : String
    "Hello, #{name}!"
  end
end
class Person
  include Greeter
  getter name : String
  def initialize(@name : String)
  end
end
puts Person.new("Alice").greet
```

Expected output:

```text
Hello, Alice!
```

[Edit and run in the Alice playground](https://playground.alice-lang.org/#code=u.bW9kdWxlIEdyZWV0ZXIKICBkZWYgZ3JlZXQgOiBTdHJpbmcKICAgICJIZWxsbywgI3tuYW1lfSEiCiAgZW5kCmVuZApjbGFzcyBQZXJzb24KICBpbmNsdWRlIEdyZWV0ZXIKICBnZXR0ZXIgbmFtZSA6IFN0cmluZwogIGRlZiBpbml0aWFsaXplKEBuYW1lIDogU3RyaW5nKQogIGVuZAplbmQKcHV0cyBQZXJzb24ubmV3KCJBbGljZSIpLmdyZWV0)

`Greeter#greet` can refer to `name` on the host class. The module is a template for that method; the compiler resolves the host's members when it includes the method in `Person`.

## Include, extend, and using

| Form        | Meaning                                                      |
| ----------- | ------------------------------------------------------------ |
| `include M` | Add module instance methods as instance methods on the class |
| `extend M`  | Add module methods as class/static methods                   |
| `using M`   | Import static module functions for unqualified calls         |
| `M::Inner`  | Qualify a nested module                                      |

These operations serve different purposes. Use `include` for behavior on objects and module static functions for utility namespaces.

```alice
module Units
  def self.km(metres : Float64) : Float64
    metres / 1000.0
  end
end
puts Units.km(2500.0)
```

Modules can nest and contain typed constants. Use namespaces and qualified names to keep unrelated APIs distinct.

## Comparable

`include Comparable` derives ordering behavior from `def <=>(other : T) : Int32`:

```alice
class Version
  include Comparable
  getter major : Int32
  def initialize(@major : Int32)
  end
  def <=>(other : Version) : Int32
    major <=> other.major
  end
end
puts Version.new(1) < Version.new(2)
```

The mixin supplies `<`, `>`, `<=`, `>=`, `==`, `between?`, and `clamp`, and implements `IComparable(T)` so sorting and min/max can use it. Make the comparison consistent with your data's intended equality.

## Enumerable

`include Enumerable` turns a class with `def each(&block : Element ->)` into an `IEnumerable(Element)`. Iterator helpers, LINQ, and `for` can then consume it.

```alice
class Bag
  include Enumerable
  def initialize
    @items = List(Int32).new
  end
  def add(x : Int32)
    @items.Add(x)
  end
  def each(&block : Int32 ->)
    for x in @items
      yield x
    end
  end
end
b = Bag.new
b.add(3)
b.add(7)
puts b.sum
```

## Reopening types

Reopening an Alice class merges its members. Reopening a .NET type such as `class String` emits extension methods rather than changing that type's runtime definition. Keep such extensions focused and avoid surprising names that collide with an existing library API.

More runtime-dependent forms are described in [dynamic features](https://alice-lang.org/documentation/language/dynamic.md).

## Continue reading

- Previous: [Structs and records](https://alice-lang.org/documentation/language/records.md)
- Next: [Generics and constraints](https://alice-lang.org/documentation/language/generics.md)
