<commit_before>---
version: 1.0.1
title: Protocols
---

In this lesson we are going to look at Protocols, what they are, and how we use them in Elixir.

{% include toc.html %}

## What Are Protocols
So what are they?
Protocols are a means of achieving polymorphism in Elixir.
One pain of Erlang is extending an existing API for newly defined types.
To avoid this in Elixir the function is dispatched dynamically based on the value's type.
Elixir comes with a number of protocols built in, for example the `String.Chars` protocol is responsible for the `to_string/1` function we've seen used previously.
Let's take a closer look at `to_string/1` with a quick example:

```elixir
iex> to_string(5)
"5"
iex> to_string(12.4)
"12.4"
iex> to_string("foo")
"foo"
```

As you can see we've called the function on multiple types and demonstrated that it work on them all.
What if we call `to_string/1` on tuples (or any type that hasn't implemented `String.Chars`)?
Let's see:

```elixir
to_string({:foo})
** (Protocol.UndefinedError) protocol String.Chars not implemented for {:foo}
    (elixir) lib/string/chars.ex:3: String.Chars.impl_for!/1<commit_msg>Update protocols.md (#2646)<commit_after>---
version: 1.0.1
title: Protocols
---

In this lesson we are going to look at Protocols, what they are, and how we use them in Elixir.

{% include toc.html %}

## What Are Protocols
So what are they?
Protocols are a means of achieving polymorphism in Elixir.
One pain of Erlang is extending an existing API for newly defined types.
To avoid this in Elixir the function is dispatched dynamically based on the value's type.
Elixir comes with a number of protocols built in, for example the `String.Chars` protocol is responsible for the `to_string/1` function we've seen used previously.
Let's take a closer look at `to_string/1` with a quick example:

```elixir
iex> to_string(5)
"5"
iex> to_string(12.4)
"12.4"
iex> to_string("foo")
"foo"
```

As you can see we've called the function on multiple types and demonstrated that it works on them all.
What if we call `to_string/1` on tuples (or any type that hasn't implemented `String.Chars`)?
Let's see:

```elixir
to_string({:foo})
** (Protocol.UndefinedError) protocol String.Chars not implemented for {:foo}
    (elixir) lib/string/chars.ex:3: String.Chars.impl_for!/1
{'fraction_non_alphanumeric': 0.09614551754006063, 'fraction_numerical': 0.015591165006496318, 'mean_word_length': 4.5, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5878036', 'n_tokens_mistral': 774, 'n_tokens_neox': 714, 'n_words': 327}