I think your protocols version is great, but you should implement all the functions:
def perimeter(%Circle{radius: radius}) do
2 * :math.pi() * radius
end
It seems that even structs that don’t implement all the functions in a protocol have dummy placeholders. Here’s an example from the core library for Function, which doesn’t implement all the functions of Enumerable:


















