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