zip with fieldTuple

Brad Anderson via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Jun 6 17:59:31 PDT 2014


On Friday, 6 June 2014 at 23:18:49 UTC, John wrote:
> On Friday, 6 June 2014 at 22:27:38 UTC, bearophile wrote:
>> John:
>>
>>> I can iterate over the struct elements with the traits 
>>> FieldTypeTuple!foo,
>>
>> In such iteration you are using a static foreach. Types are 
>> compile-time constructs in D. If you need run-time entities 
>> you need to get their typeinfo.
>
> I don't want to do that lookup at runtime though. Clearly my 
> intent is to rewrite this foreach zip expression as:
>
> auto s = test.split(",");
>
> writeln(to!int(s[0]));
> writeln(to!float(s[1]));
>

What I wrote in my reply expands to exactly that. It's an array 
indexing which is very cheap (an addition on a ptr, basically). I 
can't think of a way to make this any faster if test is a runtime 
value. If test were a compile time value you could write it in 
such a way that it distills down to:

writeln(1);
writeln(2.0);

But I suspect that's not what you are going for because test is 
meant to come in at runtime.

>> zip only works on run time values. So you can't zip a built-in 
>> typetuple of types with a range of values.
>
> Conceptually that is what I want to do though. I want to pair 
> the type with the string that I'm going to convert.
>
>>> I'm not sure if it's actually a range? I assumed it would be 
>>> a range of some kind,
>>
>> It's not a range. FieldTypeTuple returns a built-in typetuple 
>> that in this case is really a built-in of types, that are 
>> purely compile-time entities.
>
> I get that.
>
>>> and each of the elements would have a supertype of something 
>>> like 'type' since that's what they are.
>>
>> They are types (and they aren't other things like 
>> uninstantiated templates that in D are another kind), but not 
>> even in our dreams there is a supertype for them :-)
>>
>>
>>> It could infer that now you have two ranges, one of 'type' 
>>> and one of 'string'.
>>
>> Nope.
>>
>>
>>> If I'm able to foreach over two things, shouldn't I be able 
>>> to foreach over the paired ranges with zip? It seems so 
>>> simple...
>>
>> If you turn the built-in typetuple of types into an array or 
>> lazy range of typeinfo, then you can zip them. But I don't 
>> think this is a good idea. It's better to forget the zipping 
>> and use a static foreach on the types, using also an index, 
>> and use such index to access the second array of run time 
>> values.
>
> I had already considered a workaround like that, but it's just 
> that. A workaround. You already do unrolling for templates, 
> this isn't much different (at least conceptually).
>
> You could basically do exactly what you're describing in the 
> library, no? Have zip loop over all the static/compile time 
> fields (assuming you can separate them in the template from the 
> runtime ranges), and index into (or pop range) the runtime 
> ranges with length checks. The compiler would unroll the 
> compile time ranges (or whatever you want to call them) 
> creating essentially exactly what you've described, the other 
> poster mentioned, and precisely what I put above.
>
> Is that not possible?
>



You could do something kind of like what you are describing, yes, 
but you have to remember that compile time values are passed in 
as template parameters.  It'd have to look something like:

zipWithTypes!(FieldTypeTuple!foo)(test.split(","))

And the element type of the result would have to be something 
like Variant if it's going to be a range. You could use a Tuple 
too if you don't care about the result having a range interface.

Or you could represent types in runtime code with enums or 
something, like bearophile was saying.


More information about the Digitalmars-d-learn mailing list