Welcome. In this unit, you will get your first hands-on look at Elixir protocols. Protocols let you write one API that behaves differently based on the data type, which is Elixir’s way of doing polymorphism. Today, you will define a protocol and implement it for several built-in types, then call it and see dynamic dispatch in action. In later units, we will extend this idea to custom structs and then connect it to behaviors to design larger systems.
This defines a protocol named Stringify with one required function, to_string/1. The protocol itself does not implement behavior. It only declares the function signature that all implementations must provide.
By setting @fallback_to_any true, you allow the protocol to look for a default implementation if a specific one isn't found for a given type.
Each defimpl block ties the Stringify protocol to a specific type:
Integer: returns a formatted string with the integer value.List: useslength/1to report the number of items.Map: usesmap_size/1to report how many keys it has.Any: provides a default behavior for any type that doesn't have a specific implementation.
Key idea: Every implementation must define all functions declared in the protocol. If a type does not have an implementation and you have not provided a fallback for Any, Elixir will raise a Protocol.UndefinedError.
Note: Implementations can live in separate files or apps. Protocol implementations are consolidated at compile time for performance. Keep implementations available at compile time to avoid missing or stale protocol dispatch.
Each call routes to the matching implementation:
42hits theIntegerimplementation:Integer: 42[1, 2, 3]hits theListimplementation:List with 3 items%{...}hits theMapimplementation:Map with 2 keys3.14(a Float) hits theAnyimplementation:Fallback: 3.14
This is polymorphism without conditionals. You call the same function, and Elixir picks the right behavior based on the value’s type.
You defined a protocol, implemented it for Integer, List, Map, and a fallback Any type. You learned that dispatch is by the type of the first argument and that @fallback_to_any allows you to handle unknown types gracefully.
Next, you will practice to lock in the concepts and build confidence. Then we will move on to using protocols with your own structs and, later, connect these ideas to behaviors to design flexible systems.
