Tuple IFTI with implicit conversions
Reiner Pope
some at address.com
Fri Oct 19 22:03:39 PDT 2007
(A follow-up from "Any ideas for lazy evaluation on varaible argument
functions?")
Daniel Keep wrote:
> Sadly, I don't think there's any way to fix this. The problem is that
> if you've got IFTI (which is what allows you to omit the explicit
> template instantiation), the arguments can't be very complex. What you
> would need is something like this:
>
> void infoF(A...)(lazy DecayStaticArrays!(A) a) { ... }
>
> Where "DecayStaticArrays" turns all statically-sized arrays into
> dynamically-sized ones: so (char[2u], char[6u]) would become (char[],
> char[]).
This kind of problem with IFTI seems to come up from time to time. I
think the general case of this problem is when you want the parameter
types[1] to be something which the argument types[1] are implicitly
convertable to. This could be like the example above (where char[6u] is
implicitly convertable to lazy char[]) or perhaps some function which
takes the biggest integer type of the parameters:
BiggestIntType!(A) max(A...)(BiggestIntType!(A)[] params...) { ... }
Unfortunately, the above function won't work with IFTI. Normally, the
"standard" solution to this would be to have a wrapper template:
BiggestIntType!(A) max(A...)(A a) {
max_impl!(A)(a);
}
BiggestIntType!(A) max_impl(A...)(BiggestIntType!(A)[] params...) { ... }
so that the wrapper ensures IFTI still works, and it simply passes on
the argument types to the wrapper. Although this solution works here, it
doesn't solve Daniel's problem, and it ends up being repeated whereas I
think the language should essentially support doing it for you.
More valuable would be the existence of some tuple in a function
template which was a tuple of the argument types[1] for a function. I'm
not fussed about the syntax, but the point is that argtypes is simple to
evaluate: just take typeof() of each of the argument expressions at the
call-site, and stick them together as a tuple. Since there's no pattern
matching involved, IFTI can't fail. So, the examples above would become:
BiggestIntType!(A) max (argtypes A)(BiggestIntType!(A)[] params...) { ... }
and
void infoF(argtypes A)(lazy DecayStaticArrays!(A) a) { ... }
They look almost exactly the same, but the argtypes syntax says to the
compiler, "don't try to pattern-match the parameters against lazy
DecayStaticArrays!(A), instead just tell me what they are." Supposing
you used the above syntax, then it would have the rules:
1. The argtypes parameter must always go last, even after variadic
parameters
2. It is impossible to manually instantiate an argtypes parameter.
What do you think?
---
[1]: Here's what I mean when I distinguish parameter and argument types:
void foo(long x) { ... }
void main()
{
int y;
foo(y);
}
Here, I call long the parameter type, and int the argument type. The
distinction is that the argument type is the type of the expression at
the call site.
-- Reiner
More information about the Digitalmars-d
mailing list