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).

Reply via email to