Applying a tuple to a function (and more)

Philippe Sigaud philippe.sigaud at gmail.com
Sun Sep 19 06:53:27 PDT 2010


> instead of a virtual function, but I'll keep the current design because is
> simpler for me (I'm still adapting my brain to all this genericity).
>

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


>
> On my current implementation with functions I still have a doubt:
>
> I'm using template-functions like this one for my callbacks:
>
> void somefunc(T...) (string regex, T args...) {
>    foreach (arg; args) {
>        writeln(arg);
>    }
> }
>

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) {
...



>
> Then, I write the "selector" for it (in other part of the program) like
> this:
>
> auto t = tuple("someregex", &(module.somefunc!(int,
> double)),tuple(2,3.14));
>

A tuple in a tuple, nice.


>
> And then in a third module, I get those selectors and bind them to the
> functions like:
>
> auto selectable = t.field[1];
> selectable(t.field[0], t.field[2].expand); // Called!
>
> With your help, this works like a charm.
>
> But sometimes there will be no variable arguments to "somefunc" (only the
> first string), and in that case I don't know what would be the correct
> syntax to specify that the variable number of arguments will have no args,
> both for the template instantiation and for the tuple:
>
> auto t = tuple("bla", &(module.somefunc!(void), tuple(void)); // Fails
> auto t = tuple("bla", &(module.somefunc!(void, Tuple!(void)()); // Fails
> too
>

Use tuple(). Or Tuple!()()

Another possibility could be to write your selector like this:

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..$]);

for now, you cannot directly get a slice from the tuple. You either use
expand (an expression tuple, so slicable) or use the Tuple.slice member
function (never used it).


As to the difference between Tuple!(void) and Tuple!():
void is a 'valid' type (sort of). It's just a type that has no value. So
Tuple!(void) and Tuple!() are different.
You can define the type Tuple!(int, void, int), but you cannot create a
value of that type, because the void field cannot have a value.

Tuple!() is a tuple with no field, an empty tuple. You can create it all
right. It's just, its length is zero, and it has no field.
If you open it with expand, you get a zero-length typetuple. It's like an
array of length zero: it's valid, but you cannot access its internal values,
because there is none. Other programming languages call this the Unit type,
because it's a (the) type that has only _one_ value, namely Tuple!()().


If you ask for the parameter typetuple for a no-arg function, you'll get a
zero-length typetuple:

int foo() { return 0;}
alias ParameterTypeTuple!foo Pfoo;
assert(is(Pfoo == TypeTuple!());

Pfoo pfoo; pfoo is a tuple of length 0.
auto a = foo(pfoo); // we can pass it to a function with no arg.


Philippe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d-learn/attachments/20100919/f64d49cb/attachment.html>


More information about the Digitalmars-d-learn mailing list