On Tuesday, 16 July 2013 at 21:12:36 UTC, Ali Çehreli wrote:
On 07/16/2013 02:01 PM, Ali Çehreli wrote:

> On 07/16/2013 01:40 PM, JS wrote:

>  > It would be nice if we had some way to data globally(in
module).
>  >
>  > e.g., __ctfestore["name"] = value;
>
> I would expect model-level objects start their lives after
the program
> starts running but their initial value can be calculated
during compile
> time:
>
> import std.stdio;
> import std.conv;
>
> int[string] ctfestore;
>
> static this()
> {
>      ctfestore = A!().globalFunc();
> }

Ok, I've been silly. That's not CTFE. I meant something like this:

static this()
{
    enum initialValue = A!().globalFunc();
    ctfestore = initialValue;
}

And only then I got the problem:

> template A()
> {
>      int c;
>
>      int[string] globalFunc()
>      {
>          int[string] result;
>
>          void func()
>          {
>              for ( ; c < 10; ++c) {

Error: static variable c cannot be read at compile time
       called from here: func()
       called from here: globalFunc()

>                  result[c.to!string] = c;
>              }
>          }
>
>          func();
>          return result;
>      }
> }
>
> void main()
> {
>      writeln(ctfestore);
> }
>
> Prints:
>
> ["0":0, "4":4, "8":8, "1":1, "5":5, "9":9, "2":2, "6":6,
"3":3, "7":7]

Ali

yes, that error is the bitch that D loves to slap me with constantly when using ctfe's and I have to use wierd methods to get around it. Note that I am mainly talking about string mixins but the issue is that c is a template variable which is a compile time construct that has no real meaning inside a ctfe(if that makes sense). This is why nested functions have to be used... but then if you want global variables(cross-template variables) you need some other technique, if it's even possible.

template A() {
int c; // doesn't create a variable c for functions in the template to use but tells the template define a variable when used, I guess, as a normal template(not a mixin).

That is, I was initially thinking `int c;` created a compile time variable inside the template but it doesn't... c does't even exist until the template is used, but by then, it's too late... specially if the template is used as a string mixin.

I think we would need somethign like

template A() {

template int c; // or possibly internal int c;

which defines c as a template variable(not a symbolic expression inserted into code where A is used.

here is code that makes it clear:
module main;

import std.stdio, std.cstream, std.conv;

template A()
{
    int c;
    int foo() { return ++c; }
enum A = foo(); // Comment out to change A to a standard template
}


void main(string[] argv)
{       
        alias A!() a;
        //writeln(a.c, a.foo());
        writeln(a);
}

Note that A is used two different ways. A as a sort of function itself(with return foo() and, if that line is commented out, as a sort of container holding an int and a function.

I think this is the confusion that I had not realizing they are two different beasts.

When A is acting as a container, foo can use c no problem. When A is acting as a ctfe, foo can't use c. I'm not sure if this is a flaw, bug, or what...

I don't see any reason why it can't work both ways, and nesting the template as a function works to solve the compile time error.

I think both concepts can be unified by having the compiler implicitly wrap everything inside the template in a function, accept assignments to A, when used as a ctfe. (this may not work well though but a start in the right direction)



Reply via email to