Mixin templates are a pain at best, useless at worst for any non-trivial use case
Ethan
gooberman at gmail.com
Tue Jun 5 10:11:49 UTC 2018
I've come across this before with Binderoo, but now I've got
really simple use cases.
Rather than having one unmaintainable mess of a file that handles
everything (for a really egregious example, see
std.datetime.systime which has the distinction of both its source
code and documentation being unreadable), I decided to do
something similar to C#'s partial classes and use mixin templates
declared in other modules to complete the implementation.
This is all well and good until you get to dealing with function
overloads.
Exhibit A: https://run.dlang.io/is/a85Lbq
As soon as you have an overload of a function declared in the
base object you're mixing in to, any other overload mixed in will
not resolve correctly. Great.
The core use case I derived this from is client/server message
handling, and I plan on reusing mixins across client/server types
since message handling will also require variables added in to
the object to do so. Simple example: Handling Ping and Pong will
require the Ping sender to start a timer and resolve it on
receiving Pong. The partial class model is perfect for this, and
mixins are the closest we have to this.
I submitted a bug with the above code, and it was "helpfully"
shut down with a link to the documentation and workaround.
Congratulations. That's not the use case here, and to be quite
honest this is one of those examples where a #define macro would
"just work". And I'm firmly of the view that *ANY* example of
that should be dealt with at a language level in order to
completely remove the argument of needing a preprocessor.
Exhibit B: https://run.dlang.io/is/s2BJUO
This one fired as soon as Binderoo tried to do its thing: Doing
an allMembers pass of the object will list your entirely-mixed-in
overload as a member, but attempting to get that member will
resolve the symbol to void.
Great. So functions that otherwise completely resolve as a member
of a class actually don't resolve as a member of a class? Huh? I
don't even.
To see where I'm going with this, exhibit C:
https://run.dlang.io/is/KWN9yA
Rather than mixin things one by one and manually handle errors
and language shortcomings, I'm using helpers to wholesale add
functionality to my object.
And, honestly, with this method, I am already seeing the
workaround. Because I've had to do it a ton of times already with
other templates. Run a search for 'mixin( "import' in Binderoo to
see how many times I've had to get around the changes to template
visibility rules. Rather than do that though, now I'll have to
iterate over every member of a stored mixin and alias them in to
the surrounding object.
Sigh.
I know that simply posting this will result in a thread of people
offering workarounds. I don't need or want them. Why? Because the
next person that tries to do this will have the same problems.
And rather than the "correct" way to do this be voodoo knowledge
found by a Google search if you're lucky, I would far prefer this
thread become a discussion on how to improve mixins so that a DIP
can be written and resolved. So that the next person can express
language as simply as possible and have it all Just Work(TM).
More information about the Digitalmars-d
mailing list