www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Multiple Tuple IFTI Syntactic Sugar

reply dsimcha <dsimcha yahoo.com> writes:
I've been thinking about how IFTI works for variadic function templates.  I
use variadic functions heavily in the infotheory module of dstats, and am
looking to add some features here.  Currently, my mutual information function
looks like:

real mutualInfo(T, U)(T[] x, U[] y);

I'd like to generalize this so that both x and y can be any number of vectors,
yielding in standard mathematical notation, something like I(x, y; z, a),
which is the mutual information of (x, y) as a joint distribution with (z, a)
as a joint distribution.  However, trying to turn this into D code with decent
notation leads to some headaches:

real mutualInfo(T..., U...)(T x, U y);

If I call this as something like:  mutualInfo(x, y, z, a), this is obviously
ambiguous.  If I explicitly instantiate one of the tuples (assuming bug 2599
gets fixed), then this leads to some rather horrible looking notation.  If I
only use one big tuple, I have to pass in an extra parameter to indicate the
boundary between x and y, again making the notation quite ugly.

Would it be possible to add some feature where I could call mutualInfo(x, y;
z, a) or mutualInfo(x, y: z, a) or something?  The idea is that some delimiter
other than the comma would indicate what the boundaries are between two
variadic parameters.  Is this reasonable or is it too much of a niche feature?
Feb 01 2009
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
dsimcha:
 Would it be possible to add some feature where I could call mutualInfo(x, y;
 z, a) or mutualInfo(x, y: z, a)

What about mutualInfo(x, y)(z, a) ? Bye, bearophile
Feb 01 2009
prev sibling parent reply Christopher Wright <dhasenan gmail.com> writes:
dsimcha wrote:
 I've been thinking about how IFTI works for variadic function templates.  I
 use variadic functions heavily in the infotheory module of dstats, and am
 looking to add some features here.  Currently, my mutual information function
 looks like:
 
 real mutualInfo(T, U)(T[] x, U[] y);
 
 I'd like to generalize this so that both x and y can be any number of vectors,
 yielding in standard mathematical notation, something like I(x, y; z, a),
 which is the mutual information of (x, y) as a joint distribution with (z, a)
 as a joint distribution.  However, trying to turn this into D code with decent
 notation leads to some headaches:
 
 real mutualInfo(T..., U...)(T x, U y);

How do you instantiate that? mutualInfo!(TypeTuple!(T1, T2, T3), TypeTuple!(T4, T5, T6))? No, the tuples would be flattened. Bearophile's suggestion can be implemented something like: struct MutualInfo(T...) { T x; auto opCall(U...)(U y) {} } MutualInfo!(T...) mutualInfo(T...)(T args) { // etc }
Feb 01 2009
next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Christopher Wright (dhasenan gmail.com)'s article
 dsimcha wrote:
 I've been thinking about how IFTI works for variadic function templates.  I
 use variadic functions heavily in the infotheory module of dstats, and am
 looking to add some features here.  Currently, my mutual information function
 looks like:

 real mutualInfo(T, U)(T[] x, U[] y);

 I'd like to generalize this so that both x and y can be any number of vectors,
 yielding in standard mathematical notation, something like I(x, y; z, a),
 which is the mutual information of (x, y) as a joint distribution with (z, a)
 as a joint distribution.  However, trying to turn this into D code with decent
 notation leads to some headaches:

 real mutualInfo(T..., U...)(T x, U y);

mutualInfo!(TypeTuple!(T1, T2, T3), TypeTuple!(T4, T5, T6))? No, the tuples would be flattened. Bearophile's suggestion can be implemented something like: struct MutualInfo(T...) { T x; auto opCall(U...)(U y) {} } MutualInfo!(T...) mutualInfo(T...)(T args) { // etc }

I guess the bottom line is that, yes, this is too much of a niche feature. Oh well. Maybe when I have lot of free time I'll write a little compile time interpreter that takes arbitrary info theory expressions as a string, rewrites them in terms of joint entropies, combines terms, cancels stuff out, etc. This could lead to some interesting speedups when calculating complicated information theory expressions where there are some hidden simplifications available. I have something like this already, except AFAIK it only works at runtime.
Feb 03 2009
parent reply bearophile <bearophileHUGS lycos.com> writes:
dsimcha:
 I guess the bottom line is that, yes, this is too much of a niche feature.

Yes, but I think in D tuples have to nest. Their auto-flattening is a design mistake to be fixed, IMHO (even Perl6 fixes this). Another solution is to use a record() like the one in my dlibs, you can pass two of them to your function. It's less handy than your preferred syntax (and maybe slower too, if the compiler isn't smart enough to remove intermediate structs). See record() here: http://www.fantascienza.net/leonardo/so/dlibs/func.html Bye, bearophile
Feb 03 2009
parent bearophile <bearophileHUGS lycos.com> writes:
Bill Baxter:
 Wouldn't it be lovely if we could just use parentheses for that and he
 could call the function like:
      Something!((t1,t2,t3),(s1,s2,s3))

Well, the compiler can use your clean syntax as syntactic sugar for something like the Record (that is a kind of struct) of mine: Something!(record(t1, t2, t3), record(s1, s2, s3)) I don't know how much LDC/DMD are currently able to remove such temporary structs. It looks like an important optimization if you start using those Python-like types (Record) often enough. I presume something like this will see the light in D2. Bye, bearophile
Feb 03 2009
prev sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Wed, Feb 4, 2009 at 12:24 AM, bearophile <bearophileHUGS lycos.com> wrote:
 dsimcha:
 I guess the bottom line is that, yes, this is too much of a niche feature.

Yes, but I think in D tuples have to nest. Their auto-flattening is a design mistake to be fixed, IMHO (even Perl6 fixes this).

Wouldn't it be lovely if we could just use parentheses for that and he could call the function like: Something!((t1,t2,t3),(s1,s2,s3)) --bb
Feb 03 2009