<div class="gmail_quote">On Tue, Aug 31, 2010 at 20:03, dsimcha <span dir="ltr"><<a href="mailto:dsimcha@yahoo.com">dsimcha@yahoo.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
== Quote from Lutger (<a href="mailto:lutger.blijdestijn@gmail.com">lutger.blijdestijn@gmail.com</a>)'s article<br>
<div class="im">> Instead of std.mixins, perhaps it is better to fold the code with std.typecons<br>
> or create new modules as needed (std.pattern?).<br>
<br>
</div>I initially thought std.mixins would be a good idea, since it would be a one-stop<br>
shop for all kinds of misc. boilerplate code that doesn't really fit anywhere<br>
else, but the consensus seems to be that this is a bad way to define a module.<br>
I'll reconsider.<br></blockquote><div><br>Dunno. I quite liked std.mixins. But then, std.pattern(s?) is good too, except many people will think GoF-patterns.<br>btw, doesn't std.pattern already exist, to show some OOP-patterns already coded in D?<br>
<br>We could show some humor and call it std.boilerplate :)<br><br><br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div class="im"><br>
> There is also some private<br>
> boilerplate code here and there in phobos that help with ctfe and<br>
> metaprogramming, some people may also find that useful if packaged as a seperate<br>
> utility module.<br>
<br>
</div>Yea, that should probably be a todo.<br></blockquote><div><br>std.typecons is full of good stuff. I learnt quite a lot reading it. The Any code gave many hours of reading, compiling the resulting code in my head, so to say. Then I went a little mad ;)<br>
<br>My initial suggestion for your OP was a mixin to put in a class/struct to make it extensible: using opDispatch to transform a method call a.foo(args...) into the free function foo(a, args). That way a library author makes her class extensible, and I, as a user, add
free functions-passing-as-methods as I see fit.<br><br>template MakeExtensible()<br>{<br> auto opDispatch(string s, Args...)(Args args) if(is(typeof(mixin(s~"(this, args)"))))<br> {<br> mixin("return "~s~"(this, args);");<br>
}<br>}<br><br>It's a 3-line mixin, but it suffers from a nasty problem: opDispatch
only sees the symbols defined in the class modules, which forces the user to define the free functions in the class module and that rather defeats the point :( <br><br>The only solution I found was to make a wrapper template: struct (or class) Extend!Type that will act as a Type in most cases and uses an opDispatch to remain open. Note that 'alias this' has priority on opDispatch, so I couldn't use alias this in this case: the free-functions-as-method calls would be propagated to the wrapped struct/class and create an error there, without being rerouted through opDispatch.<br>
Anyway...<br>To solve the symbol-visibility problem, I made the whole machinery a template, which should be mixed in the main module.<br>For the user, it's trivial, add:<br><br>mixin Extensible; <br><br>in your main module (or in any module you'll use free functions, but symbol visibility will be affected ). You can then use extend(value) to get an extensible version of a class or struct.<br>
I have to complete to code to forward all operator calls to the wrapped value, since I cannot use alias this. In the end, I project to extract this part to make a generic ParallelType!Type wrapper that is not a subtype of Type (as alias this would). Indeed ExtendType is just a parallel type wich forward unknown methods to free functions.<br>
<br><br>Another proposal I have is a mixin that creates a string enum, Names, containing the local scope qualified name.<br><br>module pack.mod;<br>mixin(ScopeName); // Names is "pack.mod"<br><br>int foo(int j)<br>
{<br>mixin(ScopeName); // Names is "pack.mod.foo"<br>
}<br><br>class C(A,B)<br>{<br> struct S<br> {<br> void method()<br> {<br> mixin(ScopeName); // Once C is instantiated Names is "pack.mod.C!(type1, type2).S.method"<br>
}<br> }<br>}<br><br>And so on... The code is _heavily_ based on std.demangle.demangle, with some subtle differences to make it work at compile-time. I'm not sure that would be good practice to duplicate such a function in Phobos...<br>
Use case : as an helper for other mixins, giving them access to the local scope name. For example the local function name/class name for logging, or the current module name to test the existence of a type, etc.<br><br> <br>
</div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div class="im"><br>
> The dranges project at dsource is awesome, it wouldn't hurt to put<br>
> some of that good stuff in phobos.<br>
<br>
</div>Agreed. It's Philippe Sigaud's project and he's been recently added to the roster<br>
of Phobos devs. I assume he intends to integrate at least the more generally<br>
useful parts of dranges eventually.<br></blockquote><div><br>Thanks for the kind words, both of you. It's on my todo list on the short term (~ 1 week). I'll extract some code and propose if for review. David just has to stop launching interesting threads or asking for review of his own code :)<br>
<br>Philippe<br> <br></div></div><br>