<br><br><div class="gmail_quote">On Sun, Sep 19, 2010 at 18:33, Juanjo Alvarez <span dir="ltr">&lt;<a href="mailto:juanjux@gmail.com">juanjux@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div class="im">Philippe Sigaud wrote:<br>
<br>
&gt; What languages are you used to? You seem to do quite well with genericity<br>
&gt; :)<br>
<br>
</div>What I&#39;ve done profesionally and personally in the last year would be 90%<br>
Python, 5% Java and 5% C++. So yes, since Python is like a D with an<br>
uberauto and everything being runtime templates the real problem I have is<br>
with generic declarations :)<br></blockquote><div><br>OK, that&#39;s why you&#39;re using tuples for everything :)<br>Python&#39;s tuples are cool. I think I *learnt* what tuples were while dabbling in Python a few years ago. (Haskell&#39;s ones are great too).<br>
<br>Note that the &#39;real&#39; D tuples are expression tuples (instantiated typetuples). The &quot;T...&quot; thingies in templates, once instantiated with  T t;<br>They know their length, are indexable, slicable, iterable, etc. In a way they are random-access range with a length, only with heterogeneous types. <br>
But I don&#39;t think they were conceived as tuples in other languages, not at first. I&#39;d guess that, for Walter, they were just a natural extension/cleaning for templates, based on C++. But they are like Python&#39;s tuples! Except for one blatant limitation: they cannot be returned from a function :(<br>
But you can return a templated struct. So the basic idea is to wrap them in Tuple(T...) to be able to return them. Then std.typecons.tuple does its best to offer a interesting access to the underlying expression tuple. But it&#39;s not a first-class citizen in D: you cannot iterate them nor slice them... For now, because the situation has improved.<br>
<br>What many people coming from C++/Java do is putting their stuff in structs/classes. They tend not to use tuples that much.<br><br><br><br></div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div class="im">
</div>This is much better, no doubt. I&#39;ve changued that part too (I&#39;m really<br>
learning a lot with your posts, you should think about writing a book about<br>
D too).<br></blockquote><div><br>What I should do is moving my a** and have some code reviewed for Phobos. But it seems I can&#39;t find the time. When I&#39;ve half an hour, I try to help here instead :)<br><br><br> </div>
<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

Now I&#39;ve two new roadblocks:<br>
<br>
Roadblock1:<br>
<br>
If the tuple is defined in the same file as the code expanding it (with the<br>
template function in another file), it works. But if I move the tuple<br>
definition to another file (urls.d) the compiler gives me the error:<br>
<br>
Error: Unions with overlapping fields are not yet supported in CTFE<br>
urls.d(9): Error: cannot evaluate tuple(&quot;^/home/$&quot;,&amp; index,42,3.14) at<br>
compile time<br>
urls.d(9): Error: cannot evaluate tuple(&quot;^/home/$&quot;,&amp; index,42,3.14) at<br>
compile time<br>
<br>
That is, this works:<br>
<br>
// file: bindselector.d<br>
import std.typecons;<br>
import views;<br>
<br>
void main() {<br>
     // tuple defined here<br>
     auto selector_data = tuple( &quot;^/home/$&quot;, &amp;(views.index!(int, double)),<br>
42, 3.14 );<br>
     auto sel_regex_var  = selector_data.field[0];<br>
     auto sel_view_var = selector_data.field[1];<br>
     sel_view_var(sel_regex_var, selector_data.expand[2..$]);<br>
}<br>
<br>
<br>
But moving the declaration of &quot;selector_data&quot; to a file urls.d and then<br>
importing that file from bindselector.d gives me that error... bug?<br></blockquote><div><br>What do you mean, you moved the declaration of selector_data ? You declared it outside main() in another module? I don&#39;t know why, I never declare date outside functions/objects. <br>
<br>Maybe if you declare it in the &#39;root scope&#39; of the module (I don&#39;t know how to call that: the basic scope of a module, the one where the module name; is), it&#39;s initialized at compile time. And at compile time, I&#39;m not sure things like addresses &amp;(...) have a sense.<br>
<br>Did you try to make selector_data a function?<br>
<br>
auto selector_data() { return tuple(&quot;^/home/$&quot;, &amp;(views.index!(int, double)),42, 3.14 );}<br><br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

Roadblock2:<br>
The next step is to define multiple tuples in urls.d inside some iterable<br>
data structure, so bindselector.d can import that and do its thing inside a<br>
foreach.<br>
<br>
The problem here is related again with my limitations declaring generics.<br>
Since every tuple will have a different type signature, I tought that the<br>
logical structure to group them would be... yes, another tuple :) Then I<br>
would foreach on that structure and bind the params, etc.<br>
<br>
First try (Fail-1):<br>
<br>
// ----------------------------------------<br>
auto selector_data_tuples = tuple(<br>
                                   tuple( &quot;^/home/$&quot;, &amp;(views.index!(int,<br>
double)), 42, 3.14 )<br>
                                 );<br>
<br>
foreach(selector_data; selector_data_tuples) {<br>
     auto sel_regex_var  = selector_data.field[0];<br>
     auto sel_view_var = selector_data.field[1];<br>
     sel_view_var(sel_regex_var, selector_data.expand[2..$]);<br>
}<br>
// ----------------------------------------<br>
<br>
Compile error: Error: cannot infer type for selector_data<br>
<br>
Logical, since the type of the iterated element in the foreach is fixed, and<br>
I&#39;m iterating over tuples of different types.<br></blockquote><div><br>Oh, but you can iterate on an expression tuple alright, even when all its elements have different types. I don&#39;t know why bearophile doesn&#39;t like that.<br>
It&#39;s just, as I&#39;ve said higher up in this message, that tuple()/Tuple!() is a struct, not a &#39;real&#39; tuple: it offers a nice access to the wrapped expression tuple, but not as much as you&#39;d like. Use .expand to get direct access:<br>
<br><br>    auto t = tuple(1, 3.14, &quot;abc&quot;);<br>    foreach(i, field; t.expand) // get index and value<br>    {<br>        writefln(&quot;field #%s is of type %s and has value %s.&quot;,i,typeof(field).stringof, to!string(field));<br>
    }<br><br>If you want to do some type sorcery, you can also iterate on the types. You can get access to them by the .Types alias in Tuple!(). <br><br>foreach(i,Type;  t.Types) // will iterate on (int,double,string) and not on (1, 3.14, &quot;abc&quot;)<br>
{...}<br><br><br>Philippe<br><br></div></div>