www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What do you use opDispatch for?

reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
OK, I know opDispatch just appeared in DMD, but I remember a *huge* thread on
it, where people were jumping up and down waiting for it.

Me, I have no wonderful idea, though I feel some potential in it.
The only interesting use I found for now is making a class/struct extensible:

mixin template Extensible()
{
    auto opDispatch(string s, T...)(T ts)
    {
        mixin("return " ~ s ~ "(this, ts);");
    }
}

So given:

class C { 
    mixin Extensible;
}

and 

class D : C {} // (D inherits from C's extensibility).

If can 'add' methods to C and D by defining external functions: 

int foo(C c, int i) { return i;}
C c = new C;
c.foo(3); // becomes foo(c, 3).

It allows me to imitate what the compiler does for arrays:

"abc".toupper.reverse; // -> "CBA"

This functions can be templated, giving a new functionality to all extensible
classes:

string typeof(C)(C c) { return C.stringof;}

C build(C, T...)(C c, T t) if (is(C == class)) { return new C(t);}
C build(C, T...)(C c, T t) if (is(C == struct)) { return C(t);}

bool isSubtypeOf(C, D)(C c, D d) if (is(C : D)) { return true;}
bool isSubtypeOf(C, D)(C c, D d) if (!is(C : D)) { return false;}

etc.

So, is this a good idea or not? I use something like .build to map factory
functions on struct ranges, building another range of structs with different
values, but I do not _need_ mixin Extensible for this...

As for you, what are your experiences / projects with opDispatch?

Philippe
Mar 21 2010
next sibling parent reply BCS <none anon.com> writes:
Hello Philippe,

 OK, I know opDispatch just appeared in DMD, but I remember a *huge*
 thread on it, where people were jumping up and down waiting for it.
 
 Me, I have no wonderful idea, though I feel some potential in it. The
 only interesting use I found for now is making a class/struct
 extensible:
 
[...]
 
 As for you, what are your experiences / projects with opDispatch?
 
My unitted type uses it for it's value<->unit properties to get a single point of definition for each unit: http://www.dsource.org/projects/scrapple/browser/trunk/units/si2.d I've also been thinking of a way to build a compile time LINQ like program. If the comparison and boolean operators are overloadable, you could build prepared SQL queries from expressions at compile time. using(myDatabase.tables.baz.bar) foreach(Row!(int) row; select!("baz.foo").whare(for.a != someInt && baz.c == bar.c)) do(row.foo);
 Philippe
 
-- ... <IXOYE><
Mar 21 2010
parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Sun, Mar 21, 2010 at 23:02, BCS <none anon.com> wrote:


 My unitted type uses it for it's value<->unit properties to get a single
 point of definition for each unit:
 http://www.dsource.org/projects/scrapple/browser/trunk/units/si2.d
Ah, I see, that's nice. You use the received string to feed another template and generate what you need. Good idea. Why did you make OfType opDispatch a static function?
 I've also been thinking of a way to build a compile time LINQ like program.
 If the comparison and boolean operators are overloadable, you could build
 prepared SQL queries from expressions at compile time.

 using(myDatabase.tables.baz.bar)   foreach(Row!(int) row;
 select!("baz.foo").whare(for.a != someInt && baz.c == bar.c))
     do(row.foo);
If you have a limited number of methods like .whare, why use opDispach? (Sorry if my question is naive). Philippe
Mar 22 2010
parent BCS <none anon.com> writes:
Hello Philippe,

 On Sun, Mar 21, 2010 at 23:02, BCS <none anon.com> wrote:
 
 My unitted type uses it for it's value<->unit properties to get a
 single point of definition for each unit:
 http://www.dsource.org/projects/scrapple/browser/trunk/units/si2.d
 
Ah, I see, that's nice. You use the received string to feed another template and generate what you need. Good idea. Why did you make OfType opDispatch a static function?
So that "OfType.someunit(val)" becomes a free function.
 I've also been thinking of a way to build a compile time LINQ like
 program. If the comparison and boolean operators are overloadable,
 you could build prepared SQL queries from expressions at compile
 time.
 
 using(myDatabase.tables.baz.bar)   foreach(Row!(int) row;
 select!("baz.foo").whare(for.a != someInt && baz.c == bar.c))
 do(row.foo);
 
If you have a limited number of methods like .whare, why use opDispach? (Sorry if my question is naive).
The opDispatch gets used for the .a and .c bits. The above expression would get translated so that the !=/== expressions just collect values at runtime and pass them off as parameters of a prepared SQL statement whose string is built at compile time. For instance the above might result in the following string literal being used: "select baz.foo from baz join bar where a = % and baz.c == bar.c" -- ... <IXOYE><
Mar 22 2010
prev sibling parent Mike Parker <aldacron gmail.com> writes:
Philippe Sigaud wrote:
 
 
 As for you, what are your experiences / projects with opDispatch?
 
 Philippe
I was toying around with the idea of using it for a quick & dirty logger and came up with this: ************************** import std.stdio; import std.string; struct Log { File file; this(string filename) { file.open(filename, "w"); } void opDispatch(string s, string f = __FILE__, uint line = __LINE__, S...)(S args) { file.writeln("[", f, " ", line, "][", toupper(s), "]", args); } } ************************** And then use it like this: log.error("This is an error."); log.info("Wouldn't you like to know something?"); debug log.trace("Hey, this is happening now."); version(AudioStats) log.audio("Some stats: ", foo, bar); To me, this is much cleaner than the alternative, which would be something like: log.write("ERROR", "This is an error");
Mar 22 2010