Applying a tuple to a function (and more)

Juanjo Alvarez juanjux at gmail.com
Sun Sep 19 09:33:48 PDT 2010


Philippe Sigaud wrote:

> What languages are you used to? You seem to do quite well with genericity
> :)

What I've done profesionally and personally in the last year would be 90% 
Python, 5% Java and 5% C++. So yes, since Python is like a D with an 
uberauto and everything being runtime templates the real problem I have is 
with generic declarations :)
 
 
> OK, no need for the last "..."  args is already variadic. What you wrote
> is
> equivalent  "I want any number of lists of any number of types".
> Just use:
> 
> void somefunc(T...)(string regex, T args) {

Changued!

>> auto t = tuple("someregex", &(module.somefunc!(int,
>> double)),tuple(2,3.14));
>>
> 
> A tuple in a tuple, nice.

And maybe a tuple in a tuple in a tuple :) (see my other question later)
 
> auto t = tuple("bla", &(someFun), 2, 3.14);
> 
> That is, the values are not wrapped in a tuple, but directly stored in t.
> That way, if you want no value, just do:
> auto t = tuple("bla", &(someFun)); // there is an expression tuple of
> length 0 there.
> 
> auto selectable = t[1];
> selectable(t[0], t.expand[2..$]);

This is much better, no doubt. I've changued that part too (I'm really 
learning a lot with your posts, you should think about writing a book about 
D too).
 
Now I've two new roadblocks:

Roadblock1: 

If the tuple is defined in the same file as the code expanding it (with the 
template function in another file), it works. But if I move the tuple 
definition to another file (urls.d) the compiler gives me the error:

Error: Unions with overlapping fields are not yet supported in CTFE
urls.d(9): Error: cannot evaluate tuple("^/home/$",& index,42,3.14) at 
compile time
urls.d(9): Error: cannot evaluate tuple("^/home/$",& index,42,3.14) at 
compile time

That is, this works:

// file: bindselector.d 
import std.typecons;
import views;

void main() {
     // tuple defined here
     auto selector_data = tuple( "^/home/$", &(views.index!(int, double)), 
42, 3.14 );
     auto sel_regex_var  = selector_data.field[0];
     auto sel_view_var = selector_data.field[1];
     sel_view_var(sel_regex_var, selector_data.expand[2..$]);
}


But moving the declaration of "selector_data" to a file urls.d and then 
importing that file from bindselector.d gives me that error... bug? 


Roadblock2: 
The next step is to define multiple tuples in urls.d inside some iterable 
data structure, so bindselector.d can import that and do its thing inside a 
foreach.

The problem here is related again with my limitations declaring generics. 
Since every tuple will have a different type signature, I tought that the 
logical structure to group them would be... yes, another tuple :) Then I 
would foreach on that structure and bind the params, etc.

First try (Fail-1):

// ----------------------------------------
auto selector_data_tuples = tuple(
                                   tuple( "^/home/$", &(views.index!(int, 
double)), 42, 3.14 )
                                 );

foreach(selector_data; selector_data_tuples) {
     auto sel_regex_var  = selector_data.field[0];
     auto sel_view_var = selector_data.field[1];
     sel_view_var(sel_regex_var, selector_data.expand[2..$]);
}
// ----------------------------------------

Compile error: Error: cannot infer type for selector_data

Logical, since the type of the iterated element in the foreach is fixed, and 
I'm iterating over tuples of different types.

Then I did (Fail-2):

// -----------------------------------------------------------
     for (int i = 0; i < selector_data_tuples.length; i++) {
         auto selector_data = selector_data_tuples.field[i];
         auto sel_regex_var  = selector_data.field[0];
         auto sel_view_var = selector_data.field[1];
         sel_view_var(sel_regex_var, selector_data.expand[2..$]);
     }
// -----------------------------------------------------------

Which fails with a "Error: Integer constant expression expected instead of 
cast(uint)i".

Is there any other way to iterate over a tuple with values of different 
tuples? Does d provide any other data structures better suited for this 
case? (other than an array of Object and a gazillion ugly casts). 





More information about the Digitalmars-d-learn mailing list