My initial reaction is that there’s something missing / inconsistent with the example:
-
the private
do_write
functions that are injected byuse IWriter
don’t appear to be called anywhere -
the
write_with
functions inTextWriter
aren’t called anywhere either -
calling a function through this mechanism requires accessing the internals of an opaque type (with
nw.writer
)
There are some other parts that seem odd:
-
in
TextWriter
,@type wrt :: IWriter
- this declareswrt
as a type inhabited by exactly one member, the atom:"Elixir.IWriter"
. You’d typically see this kind of construct used to create an enum-like with multiple atoms (@type something :: :foo | :bar | :baz
) but the compiler is perfectly fine with exactly one -
similarly,
TextWriter.t()
is a struct where the only expected value of thewriter
field is that same atom. This is consistent with the typing onTextWriter.new/1
because it only promises to accept:"Elixir.IWriter"
as an argument. -
however, that means that this doesn’t satisfy the typespec:
TextWriter.new(DummyWriter)
sinceDummyWriter
is not the expected atom
Regarding the overall concept, IMO it’s reimplementing OO awkwardly with “objects” like TextWriter
needing to explicitly hold a vtable-like thing.
You may find the discussions around the removal of “tuple calls” from the BEAM back in 2017 interesting: