# Protocols and generics

A protocol names methods a type can implement. A generic bounded by it is compiled once per concrete type, so dispatch costs nothing at run time.

## Protocols and bounds

`protocol` declares the methods. `impl P for T` supplies them for one type, including a built-in type such as `Int64`.

A generic function takes a bound: `fn label<T: Show>(x: T)`. The compiler generates one `label` per concrete type and calls the implementation directly. There is no table and no dynamic lookup: the choice is made once, while compiling.

A protocol can also declare an associated type. [Chapter 11](https://vyrn-lang.github.io/guide/errors.html#fallible) uses one: `Fallible` owes an `Output`, which is what `?` hands back.

```vyrn
// A protocol names methods a type can implement. A generic bounded by it calls
// those methods, and the compiler picks the implementation while it compiles —
// one function per concrete type, no table lookup at run time.
import { joinWith } from "std/strings"

protocol Show {
    fn show(self) -> String
}

impl Show for Int64 {
    fn show(self) -> String {
        return self.toString()
    }
}

impl Show for Bool {
    fn show(self) -> String {
        if self {
            return "yes"
        }
        return "no"
    }
}

fn label<T: Show>(x: T) -> String {
    return "[" + x.show() + "]"
}

export fn demo() -> String {
    return joinWith([label(41), label(true)], "\n")
}

fn main() -> Int64 {
    print(demo())
    return 0
}
```

Built output:

```
[41]
[yes]
```

---

From https://vyrn-lang.github.io/guide/protocols.html — generated by `site/export.vyrn` from the Vyrn repository.
