Inspect protocol for recursive data types

Hello! I have a question how to properly implement Inspect protocol for custom recursive data type in Elixir. For example I implemented singly linked list here:

Implementation itself and few protocol implementations like

Are working perfectly, here is example of String.Chars test

And this is important, because this implementation is very similar to Inspect protocol implementation

But because of some reason one is working good when other not:

iex(1)> use ExList
iex(2)> list(:hello, list(:world, list())) |> to_string
"#ExList<hello, world>"
iex(3)> list(:hello, list(:world, list())) |> inspect
"%Inspect.Error{message: \"got FunctionClauseError with message \\\"no function clause matching in Kernel.inspect/2\\\" while inspecting %{__struct__: ExList.Backends.Struct, head: :hello, tail: %{__struct__: ExList.Backends.Struct, head: :world, tail: #ExList<>}}\"}"

Also I have a second question related to protocols topic. Let’s say I have data type and implementations for standard Elixir protocols (like examples above). Are there any standard test cases for standard protocols - to check that protocol implementation is valid? Something like property-based testing - you should provide generator for custom type, and automated test cases should test generic protocol functions with given generators somehow?


I’m guessing it’s failing in one of those color/container_doc or whatever helper functions, however calling it ‘through’ the protocol is hiding the error, you should call it straight instead in a test, like via Inspect.ExList.Backends.Struct.inspect(list(:hello, list(:world, list())), %Inspect.Opts{}) as that will show the full and proper stacktrace and tell you what’s happening. :slight_smile:

You can always loop over the implementations after compilation and run some tests on it, I even have that functionality baked into Protocol replacement ProtocolEx, the functionality is via the deftest call but you can still do it manually via Elixir’s normal Protocols. :slight_smile:

1 Like