<!-- Sema documentation — polymorphism
     Sema is a new AI-native, neurosymbolic programming language most models
     have not been trained on. Full corpus: https://sema.49.12.246.95.sslip.io/llms-full.txt
     Install language support: https://sema.49.12.246.95.sslip.io/install-skill/ -->

# polymorphism

> Traits, enums, and generics — Sema polymorphism without classes or inheritance.

> Traits, enums, and generics — Sema polymorphism without classes or inheritance.

Run it from `sema/`:

```bash
sema check examples/polymorphism
SEMA_STRICT=1 sema run examples/polymorphism
sema assure examples/polymorphism --grade silver
```

## Source

### `src/main.sema`

```sema
"""Polymorphism worked example (§3.9).

Demonstrates the whole trait trio and a functional pipeline in one runnable
program on the deterministic mock engine:

- a **struct conforming via the header list** (`Version`),
- a **struct conforming out of line** with `impl Ord for Money` (retrofit),
- an **enum conforming to the same trait** (`Severity`), defaults grafted too,
- a **bounded generic** `maximum[T: Ord]` reused across all three,
- **default methods** (`less`/`max2`/`clamp`) derived from one `compare`,
- a **supertrait** obligation (`Ord` requires `Eq`),
- **trait objects**: a heterogeneous `list[Renderer]` dispatched dynamically,
  with `is` narrowing (open-world polymorphism — see `plugins.sema`),
- **functional style**: immutable bindings, a comprehension, conditional
  expressions."""

assure gold

from polymorphism.order import Ord, maximum
from polymorphism.plugins import Renderer, Text, Bullet, Rule, render_all, count_rules

struct Version (Ord):
    """Ordered by major, then minor."""
    major: int
    minor: int
    def compare(self, other: Version) -> int !{}:
        return (self.major - other.major) if self.major != other.major else (self.minor - other.minor)

# Out-of-line conformance: `Money` is declared plainly, then retrofitted to
# `Ord` — the same defaults graft on as if listed in the header.
struct Money:
    minor_units: int

impl Ord for Money:
    def compare(self, other: Money) -> int !{}:
        return self.minor_units - other.minor_units

# An enum conforms to the very same trait; `less`/`max2`/`clamp` graft onto it.
enum Severity (Ord):
    low
    medium
    high
    def rank(self) -> int !{}:
        return 0 if self == Severity.low else (1 if self == Severity.medium else 2)
    def compare(self, other: Severity) -> int !{}:
        return self.rank() - other.rank()

def latest_version() -> Version !{}:
    ensure result.major == 2
    ensure result.minor == 0
    return maximum([Version(major=1, minor=4), Version(major=2, minor=0), Version(major=1, minor=9)])

def maximum_money(prices: list[Money]) -> Money !{}:
    require len(prices) > 0
    return maximum(prices)

def highest_severity() -> Severity !{}:
    ensure result == Severity.high
    return maximum([Severity.low, Severity.high, Severity.medium])

def clamped_version(value: Version, lower: Version, upper: Version) -> Version !{}:
    return value.clamp(lower, upper)

def rendered_report() -> str !{}:
    ensure result == "Report|----|- alpha|- beta"
    return render_all([Text(body="Report"), Rule(width=4), Bullet(item="alpha"), Bullet(item="beta")])

def rendered_rule_count(items: list[Renderer]) -> int !{}:
    return count_rules(items)

def default_methods_hold() -> bool !{}:
    ensure result == true
    lower = Version(major=1, minor=9)
    upper = Version(major=2, minor=0)
    return lower.less(upper) and upper.eq(Version(major=2, minor=0))

test "bounded generic selects latest Version 2.0":
    latest = latest_version()
    ensure latest.major == 2
    ensure latest.minor == 0

test "out-of-line Money impl selects maximum 1799":
    prices = [Money(minor_units=1299), Money(minor_units=999), Money(minor_units=1799)]
    ensure maximum_money(prices).minor_units == 1799

test "bounded generic preserves a maximum in the first slot":
    prices = [Money(minor_units=1799), Money(minor_units=1299), Money(minor_units=999)]
    ensure maximum(prices).minor_units == 1799

test "enum Ord dispatch selects Severity.high":
    ensure highest_severity() == Severity.high

test "enum rank distinguishes every variant":
    ensure Severity.low.rank() == 0
    ensure Severity.medium.rank() == 1
    ensure Severity.high.rank() == 2

test "default clamp returns Version 2.0":
    clamped = clamped_version(Version(major=5, minor=0), Version(major=1, minor=0), Version(major=2, minor=0))
    ensure clamped.major == 2
    ensure clamped.minor == 0

test "trait-object dispatch renders Report":
    ensure rendered_report() == "Report|----|- alpha|- beta"

test "is narrowing counts one Rule":
    items = [Text(body="Report"), Rule(width=4), Bullet(item="alpha"), Bullet(item="beta")]
    ensure rendered_rule_count(items) == 1

test "Ord defaults provide less and eq":
    ensure default_methods_hold() == true

def main() -> str !{}:
    ensure result == "latest=2.0 dearest=1799 cheaper=[1299, 999] top=high clamped=2.0 rendered=Report|----|- alpha|- beta rules=1"
    # Bounded generic over a user struct.
    latest = latest_version()

    # Retrofitted struct + a functional comprehension using a default method.
    prices = [Money(minor_units=1299), Money(minor_units=999), Money(minor_units=1799)]
    dearest = maximum_money(prices)
    cheaper = [p.minor_units for p in prices if p.less(dearest)]

    # Enum ordering through the grafted defaults.
    top = highest_severity()

    # `clamp` is a default method that calls other defaults.
    clamped = clamped_version(latest, latest, latest)

    # Trait objects: heterogeneous lists dispatch dynamically inside the wrappers.
    rendered = rendered_report()
    rules = rendered_rule_count([Rule(width=len(rendered))])

    summary = f"latest={latest.major}.{latest.minor} dearest={dearest.minor_units} cheaper={cheaper} top={top.name} clamped={clamped.major}.{clamped.minor} rendered={rendered} rules={rules}"
    print(summary)
    return summary
```

### `src/order.sema`

```sema
"""Reusable ordering vocabulary (§3.9).

`Ord` is built on the supertrait `Eq`. A conforming type supplies a single
required method — `compare` — and inherits every other operation as a *default
method*: `less`, `eq`, `max2`, and `clamp` are written once here and grafted
onto every type that conforms, with the type's own definition winning if it
provides one. `maximum` is a *bounded generic*: it works for any `T` that is
`Ord`, using only the trait's surface."""

pub trait Eq:
    """Equality by value."""
    def eq(self, other: Self) -> bool !{}

pub trait Ord (Eq):
    """A total order. Supply `compare`; the rest is provided for free."""
    def compare(self, other: Self) -> int !{}

    # --- default (provided) methods: written once, reused by every conformer ---
    def less(self, other: Self) -> bool !{}:
        return self.compare(other) < 0

    def eq(self, other: Self) -> bool !{}:
        return self.compare(other) == 0

    def max2(self, other: Self) -> Self !{}:
        return other if self.less(other) else self

    def clamp(self, lo: Self, hi: Self) -> Self !{}:
        return lo if self.less(lo) else (hi if hi.less(self) else self)

# Bounded generic (§3.9): `[T: Ord]` is erased at runtime, but the bound is the
# declared obligation that the element type provides `Ord`, so the body may use
# `max2`. Works uniformly for structs and enums that conform.
pub def maximum[T: Ord](xs: list[T]) -> T !{}:
    require len(xs) > 0
    mut best = xs[0]
    for x in xs[1:]:
        best = best.max2(x)
    return best
```

### `src/plugins.sema`

```sema
"""Trait objects (§3.9) — open-world polymorphism.

A `Renderer` trait with several unrelated concrete implementations, held
together in one `list[Renderer]` and dispatched dynamically. This is the pattern
classes use *inheritance* for (a heterogeneous collection behind an interface),
done with traits + dynamic dispatch instead — third parties can add new
`Renderer`s without touching a central `enum`. `is` recovers the concrete type
when open-world code needs it."""

pub trait Renderer:
    """Anything that can render itself to a line of text."""
    def render(self) -> str

pub struct Text (Renderer):
    body: str
    def render(self) -> str !{}:
        return self.body

pub struct Bullet (Renderer):
    item: str
    def render(self) -> str !{}:
        return f"- {self.item}"

pub struct Rule (Renderer):
    width: int
    def render(self) -> str !{}:
        return "-" * self.width

# A heterogeneous collection behind the trait, dispatched dynamically: each
# element is a different concrete type, resolved at the call site by its runtime
# type. No `enum`, no shared base class.
pub def render_all(items: list[Renderer]) -> str !{}:
    lines = [it.render() for it in items]
    return "|".join(lines)

# `is` narrowing: open-world code can still ask a value's concrete type or test
# trait conformance.
pub def count_rules(items: list[Renderer]) -> int !{}:
    mut n = 0
    for it in items:
        n = n + (1 if it is Rule else 0)
    return n
```

## Reflected API

# `main`

Polymorphism worked example (§3.9).

Demonstrates the whole trait trio and a functional pipeline in one runnable
program on the deterministic mock engine:

- a **struct conforming via the header list** (`Version`),
- a **struct conforming out of line** with `impl Ord for Money` (retrofit),
- an **enum conforming to the same trait** (`Severity`), defaults grafted too,
- a **bounded generic** `maximum[T: Ord]` reused across all three,
- **default methods** (`less`/`max2`/`clamp`) derived from one `compare`,
- a **supertrait** obligation (`Ord` requires `Eq`),
- **trait objects**: a heterogeneous `list[Renderer]` dispatched dynamically,
  with `is` narrowing (open-world polymorphism — see `plugins.sema`),
- **functional style**: immutable bindings, a comprehension, conditional
  expressions.

# `struct Version`

Ordered by major, then minor.

**Fields**

| field | type | descriptor |
|---|---|---|
| `major` | `int` |  |
| `minor` | `int` |  |

# `struct Money`

**Fields**

| field | type | descriptor |
|---|---|---|
| `minor_units` | `int` |  |

# `enum Severity`

**Variants**

- `low`
- `medium`
- `high`

# `def latest_version`

```sema
def latest_version() -> Version !{}
```

**Returns** `Version`

**Effects** `!{}`

# `def maximum_money`

```sema
def maximum_money(prices: list[Money]) -> Money !{}
```

**Parameters**

| name | type |
|---|---|
| `prices` | `list[Money]` |

**Returns** `Money`

**Effects** `!{}`

# `def highest_severity`

```sema
def highest_severity() -> Severity !{}
```

**Returns** `Severity`

**Effects** `!{}`

# `def clamped_version`

```sema
def clamped_version(value: Version, lower: Version, upper: Version) -> Version !{}
```

**Parameters**

| name | type |
|---|---|
| `value` | `Version` |
| `lower` | `Version` |
| `upper` | `Version` |

**Returns** `Version`

**Effects** `!{}`

# `def rendered_report`

```sema
def rendered_report() -> str !{}
```

**Returns** `str`

**Effects** `!{}`

# `def rendered_rule_count`

```sema
def rendered_rule_count(items: list[Renderer]) -> int !{}
```

**Parameters**

| name | type |
|---|---|
| `items` | `list[Renderer]` |

**Returns** `int`

**Effects** `!{}`

# `def default_methods_hold`

```sema
def default_methods_hold() -> bool !{}
```

**Returns** `bool`

**Effects** `!{}`

# `def main`

```sema
def main() -> str !{}
```

**Returns** `str`

**Effects** `!{}`



# `order`

Reusable ordering vocabulary (§3.9).

`Ord` is built on the supertrait `Eq`. A conforming type supplies a single
required method — `compare` — and inherits every other operation as a *default
method*: `less`, `eq`, `max2`, and `clamp` are written once here and grafted
onto every type that conforms, with the type's own definition winning if it
provides one. `maximum` is a *bounded generic*: it works for any `T` that is
`Ord`, using only the trait's surface.

# `trait Eq`

Equality by value.

# `trait Ord`

A total order. Supply `compare`; the rest is provided for free.

# `def maximum`

```sema
def maximum[T: Ord](xs: list[T]) -> T !{}
```

**Parameters**

| name | type |
|---|---|
| `xs` | `list[T]` |

**Returns** `T`

**Effects** `!{}`



# `plugins`

Trait objects (§3.9) — open-world polymorphism.

A `Renderer` trait with several unrelated concrete implementations, held
together in one `list[Renderer]` and dispatched dynamically. This is the pattern
classes use *inheritance* for (a heterogeneous collection behind an interface),
done with traits + dynamic dispatch instead — third parties can add new
`Renderer`s without touching a central `enum`. `is` recovers the concrete type
when open-world code needs it.

# `trait Renderer`

Anything that can render itself to a line of text.

# `struct Text`

**Fields**

| field | type | descriptor |
|---|---|---|
| `body` | `str` |  |

# `struct Bullet`

**Fields**

| field | type | descriptor |
|---|---|---|
| `item` | `str` |  |

# `struct Rule`

**Fields**

| field | type | descriptor |
|---|---|---|
| `width` | `int` |  |

# `def render_all`

```sema
def render_all(items: list[Renderer]) -> str !{}
```

**Parameters**

| name | type |
|---|---|
| `items` | `list[Renderer]` |

**Returns** `str`

**Effects** `!{}`

# `def count_rules`

```sema
def count_rules(items: list[Renderer]) -> int !{}
```

**Parameters**

| name | type |
|---|---|
| `items` | `list[Renderer]` |

**Returns** `int`

**Effects** `!{}`
