## digitalmars.D - Multiple Tuple IFTI Syntactic Sugar

- dsimcha <dsimcha yahoo.com> Feb 01 2009
- bearophile <bearophileHUGS lycos.com> Feb 01 2009
- Christopher Wright <dhasenan gmail.com> Feb 01 2009
- dsimcha <dsimcha yahoo.com> Feb 03 2009
- bearophile <bearophileHUGS lycos.com> Feb 03 2009
- bearophile <bearophileHUGS lycos.com> Feb 03 2009
- Bill Baxter <wbaxter gmail.com> Feb 03 2009

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

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

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

== Quote from Christopher Wright (dhasenan gmail.com)'s articledsimcha 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

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

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

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