foreach over split string
JS
js.mdnq at gmail.com
Wed Jul 17 23:39:25 PDT 2013
On Thursday, 18 July 2013 at 05:57:48 UTC, H. S. Teoh wrote:
> On Thu, Jul 18, 2013 at 07:23:57AM +0200, JS wrote:
> [...]
>> Thanks, this has made it much clearer.
>>
>> Something like
>>
>> foreach(a; StrSplit!(s))
>> foreach(b; StrSplit !(a))
>>
>> does work because the second StrSplit uses a "ctfe-time
>> variable"
>> instead of a "template-time variable".
>>
>> My logic was:
>>
>> 1. first StrSplit resolved
>> 2. first foreach evaluated
>> 3. second StrSplit resolved
>> 4. second foreach evaluated
>>
>> while it actually is
>>
>> 1. first StrSplit resolved
>> 2. second StrSplit resolved
>> 3. foreach's resolved
>>
>> because template expansion happens before any ctfe expansion.
>>
>> I guess I was thinking the compiler would be smart enough to
>> interleave template expansion and ctfe code(which would be
>> much more
>> powerfull).
>>
>> Effectively template expansion is a sort of pre-processing to
>> ctfe
>> code and must be static as far as ctfe's go.
> [...]
>
> That's one way to think of it, yes.
>
> As for interleaving template expansion vs. ctfe evaluation, the
> compiler
> *does* do that to some extent. For example, this code does
> work:
>
> // Function that can be evaluated by CTFE
> int func(int x) pure {
> int sum;
> foreach (i; 0..x) {
> sum += i;
> }
> return sum;
> }
>
> // Force CTFE evaluation
> enum myConst = func(10);
>
> // Template that requires an int parameter.
> template MyTemplate(int x) {
> enum MyTemplate = x+10;
> }
>
> // Instantiate template with enum produced by CTFE.
> pragma(msg, MyTemplate!myConst);
>
> void main() {}
>
> The reason this works is because the compiler is smart enough
> to figure
> out that myConst requires func, so it first compiles func far
> enough to
> be CTFE-evaluable, then it evaluates func to produce the value
> of
> myConst, and then myConst is used to instantiate MyTemplate.
> You could
> think of it as the compiler compiling different parts of the
> program at
> different rates, so func has been compiled into a runnable
> state, but
> the pragma(msg) line is still at the template expansion state.
>
> Note, however, that the template-before-CTFE limitation still
> applies:
> func can't require template expansion while it's running; it
> must be
> entirely compilable into runnable state before CTFE can
> evaluate it.
> Other parts of the program can still remain at the
> template-expansion
> stage, so they can take some CTFE-produced values as template
> parameters. But you can't make any reverse dependencies /
> loops. You're
> OK if you already have runnable code that can then produce
> template
> parameters for other code, but you can't run CTFE and template
> expansion
> simultaneously in the *same* code.
>
> So the compiler is actually pretty smart about reordering these
> things,
> but the fundamental limitation of template-before-CTFE still
> applies to
> each individual code unit. After all, you can't run code that
> hasn't
> been fully expanded by the template system yet.
>
>
> T
Thanks. Your reply was extremely helpful and I think I'll have
less pms over ctfe's.
More information about the Digitalmars-d-learn
mailing list