Tuple IFTI with implicit conversions

Jari-Matti Mäkelä jmjmak at utu.fi.invalid
Sat Oct 20 11:31:52 PDT 2007


Reiner Pope wrote:

> (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?

Couldn't the polysemous values be used here? E.g. caller side calls the
function with a set of possible type tuples. In the end the compiler could
choose the best match(es) or throw an error on ambiguity. The char[] <->
char[n] conversion is particularly annoying even in very trivial code - a
template doesn't sound like a good idea.

Approach with polysemous values could be extended in other ways. IFTI
functions could be overloaded. One thing that has caused me some headache
is the IsExpression - it seems to sweep under the carpet the fact that
template parameters cannot do proper static predicate dispatching. I'd like
to see a way to specify a compile time boolean function that defines
whether the pattern matches or not (arithmetics with types should have
proper semantics then - this could be extended elsewhere too, but I won't
touch that here) - a general case could look like:

void myFun(T1 : predicate_1, ..., Tn : predicate_n)(type_1 param_1, ...,
type_n param_n)

I don't think moveing the predicates to the fn parameter side (BCS's
proposal) is a good idea since it's something different that D does now.

Here's some related discussion http://lambda-the-ultimate.org/node/1655



More information about the Digitalmars-d mailing list