www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - String Mixins & Compile Time Evaluation

reply Travis Boucher <boucher.travis gmail.com> writes:
I've been playing with string mixins, and they are very powerful.

One thing I can't figure out is what exactly can and cannot be evaluated 
at compile time.

For example:

----
char[] myFunc1() {
     return "int a = 1;";
}

char[] myFunc2() {
     char[] myFunc3() {
         return "int b = 2;";
     }
     return myFunc3();
}

void main() {
     mixin(myFunc1());
     mixin(myFunc2());
}
----

myFunc1() can be used as a string mixin.
myFunc2() can't be.

Another (slightly more complex) example is using an ExpressionTuple.

----
template DataGenerator(T, M...) {
	char[] data() {
		char[] rv;
		foreach (m; M) rv ~= T.stringof ~ " " ~ m ~ ";";
		return rv;
	}
}

alias DataGenerator!(int, "r", "g", "b") ColorRGBgen;

writefln(ColorRGBgen.data()); // int R; int G; int B;

struct Color {
	mixin(ColorRGBgen.data()); // Can't evaluate at compile time
}
----


I'm sure there are other things that I'll run into, but I figure there 
is some simple set of rules of what can and can't be used as a string 
mixin and other compile time evaluations.
Nov 16 2009
parent reply Don <nospam nospam.com> writes:
Travis Boucher wrote:
 I've been playing with string mixins, and they are very powerful.
 
 One thing I can't figure out is what exactly can and cannot be evaluated 
 at compile time.
 
 For example:
 
 ----
 char[] myFunc1() {
     return "int a = 1;";
 }
 
 char[] myFunc2() {
     char[] myFunc3() {
         return "int b = 2;";
     }
     return myFunc3();
 }
 
 void main() {
     mixin(myFunc1());
     mixin(myFunc2());
 }
 ----
 
 myFunc1() can be used as a string mixin.
 myFunc2() can't be.
I think you're using an old version of DMD. It's been working since DMD1.047. Please upgrade to the latest version, you'll find it a lot less frustrating. The bottom of "function.html" in the spec gives the rules. Though it says nested functions aren't supported, but they are.
Nov 17 2009
next sibling parent reply Travis Boucher <boucher.travis gmail.com> writes:
Don wrote:
 Travis Boucher wrote:
 I've been playing with string mixins, and they are very powerful.

 One thing I can't figure out is what exactly can and cannot be 
 evaluated at compile time.

 For example:

 ----
 char[] myFunc1() {
     return "int a = 1;";
 }

 char[] myFunc2() {
     char[] myFunc3() {
         return "int b = 2;";
     }
     return myFunc3();
 }

 void main() {
     mixin(myFunc1());
     mixin(myFunc2());
 }
 ----

 myFunc1() can be used as a string mixin.
 myFunc2() can't be.
I think you're using an old version of DMD. It's been working since DMD1.047. Please upgrade to the latest version, you'll find it a lot less frustrating. The bottom of "function.html" in the spec gives the rules. Though it says nested functions aren't supported, but they are.
Yeah, I am running 1.020 with gdc (freebsd default for gdc package). I found a few work arounds, just trying to see what can be done. For now I'll take it as a work in progress and once I start doing anything real with it I'll upgrade to the latest version of dmd. Thanks, Travis Boucher
Nov 16 2009
parent Bill Baxter <wbaxter gmail.com> writes:
On Mon, Nov 16, 2009 at 8:25 PM, Travis Boucher
<boucher.travis gmail.com> wrote:
 Don wrote:
 Travis Boucher wrote:
 I've been playing with string mixins, and they are very powerful.

 One thing I can't figure out is what exactly can and cannot be evaluate=
d
 at compile time.

 For example:

 ----
 char[] myFunc1() {
 =A0 =A0return "int a =3D 1;";
 }

 char[] myFunc2() {
 =A0 =A0char[] myFunc3() {
 =A0 =A0 =A0 =A0return "int b =3D 2;";
 =A0 =A0}
 =A0 =A0return myFunc3();
 }

 void main() {
 =A0 =A0mixin(myFunc1());
 =A0 =A0mixin(myFunc2());
 }
 ----

 myFunc1() can be used as a string mixin.
 myFunc2() can't be.
I think you're using an old version of DMD. It's been working since DMD1.047. Please upgrade to the latest version, you'll find it a lot les=
s
 frustrating.
 The bottom of "function.html" in the spec gives the rules.
 Though it says nested functions aren't supported, but they are.
Yeah, I am running 1.020 with gdc (freebsd default for gdc package). =A0I found a few work arounds, just trying to see what can be done.
Ohhhh, well yeh, Don's been smashing CTFE bugs like crazy lately. I think the version you're using doesn't even have the useful error message fix that tells you what can't be CTFE'd. So definitely upgrade before you try to do anything serious with CTFE. --bb
Nov 17 2009
prev sibling parent reply Bill Baxter <wbaxter gmail.com> writes:
On Tue, Nov 17, 2009 at 2:07 AM, Don <nospam nospam.com> wrote:
 Travis Boucher wrote:
 I've been playing with string mixins, and they are very powerful.

 One thing I can't figure out is what exactly can and cannot be evaluated
 at compile time.

 For example:

 ----
 char[] myFunc1() {
 =A0 =A0return "int a =3D 1;";
 }

 char[] myFunc2() {
 =A0 =A0char[] myFunc3() {
 =A0 =A0 =A0 =A0return "int b =3D 2;";
 =A0 =A0}
 =A0 =A0return myFunc3();
 }

 void main() {
 =A0 =A0mixin(myFunc1());
 =A0 =A0mixin(myFunc2());
 }
 ----

 myFunc1() can be used as a string mixin.
 myFunc2() can't be.
I think you're using an old version of DMD. It's been working since DMD1.047. Please upgrade to the latest version, you'll find it a lot less frustrating. The bottom of "function.html" in the spec gives the rules. Though it says nested functions aren't supported, but they are.
Ah, forgot about that list. Good point. But still Travis should know that the list is not exhaustive. For instance the other day I found that this didn't work for some reason: while(i < a - b) { ... } Instead I had to do int limit =3D a-b; while(i < limit) { ... } --bb
Nov 17 2009
parent reply Don <nospam nospam.com> writes:
Bill Baxter wrote:
 On Tue, Nov 17, 2009 at 2:07 AM, Don <nospam nospam.com> wrote:
 Travis Boucher wrote:
 I've been playing with string mixins, and they are very powerful.

 One thing I can't figure out is what exactly can and cannot be evaluated
 at compile time.

 For example:

 ----
 char[] myFunc1() {
    return "int a = 1;";
 }

 char[] myFunc2() {
    char[] myFunc3() {
        return "int b = 2;";
    }
    return myFunc3();
 }

 void main() {
    mixin(myFunc1());
    mixin(myFunc2());
 }
 ----

 myFunc1() can be used as a string mixin.
 myFunc2() can't be.
I think you're using an old version of DMD. It's been working since DMD1.047. Please upgrade to the latest version, you'll find it a lot less frustrating. The bottom of "function.html" in the spec gives the rules. Though it says nested functions aren't supported, but they are.
Ah, forgot about that list. Good point. But still Travis should know that the list is not exhaustive. For instance the other day I found that this didn't work for some reason: while(i < a - b) { ... } Instead I had to do int limit = a-b; while(i < limit) { ... }
I can't reproduce it. Do you have a complete test case?
Nov 17 2009
parent reply Bill Baxter <wbaxter gmail.com> writes:
On Tue, Nov 17, 2009 at 4:17 AM, Don <nospam nospam.com> wrote:
 Bill Baxter wrote:
 On Tue, Nov 17, 2009 at 2:07 AM, Don <nospam nospam.com> wrote:
 Travis Boucher wrote:
 I've been playing with string mixins, and they are very powerful.

 One thing I can't figure out is what exactly can and cannot be evaluat=
ed
 at compile time.

 For example:

 ----
 char[] myFunc1() {
 =A0 return "int a =3D 1;";
 }

 char[] myFunc2() {
 =A0 char[] myFunc3() {
 =A0 =A0 =A0 return "int b =3D 2;";
 =A0 }
 =A0 return myFunc3();
 }

 void main() {
 =A0 mixin(myFunc1());
 =A0 mixin(myFunc2());
 }
 ----

 myFunc1() can be used as a string mixin.
 myFunc2() can't be.
I think you're using an old version of DMD. It's been working since DMD1.047. Please upgrade to the latest version, you'll find it a lot le=
ss
 frustrating.
 The bottom of "function.html" in the spec gives the rules.
 Though it says nested functions aren't supported, but they are.
Ah, forgot about that list. =A0Good point. But still Travis should know that the list is not exhaustive. For instance the other day I found that this didn't work for some reason=
:
 =A0 while(i < a - b) { ... }

 Instead I had to do

 =A0 int limit =3D a-b;
 =A0 while(i < limit) { ... }
I can't reproduce it. Do you have a complete test case?
Doh! Now I can't either. Maybe it was just a typo that I didn't notice. How about C functions? Any chance those'll ever work? Particularly C stdlib functions. They're one of the major things I'm finding prevents std.string functions from being used CTFE. --bb
Nov 17 2009
parent reply Don <nospam nospam.com> writes:
Bill Baxter wrote:
 On Tue, Nov 17, 2009 at 4:17 AM, Don <nospam nospam.com> wrote:
 Bill Baxter wrote:
 On Tue, Nov 17, 2009 at 2:07 AM, Don <nospam nospam.com> wrote:
 Travis Boucher wrote:
 I've been playing with string mixins, and they are very powerful.

 One thing I can't figure out is what exactly can and cannot be evaluated
 at compile time.

 For example:

 ----
 char[] myFunc1() {
   return "int a = 1;";
 }

 char[] myFunc2() {
   char[] myFunc3() {
       return "int b = 2;";
   }
   return myFunc3();
 }

 void main() {
   mixin(myFunc1());
   mixin(myFunc2());
 }
 ----

 myFunc1() can be used as a string mixin.
 myFunc2() can't be.
I think you're using an old version of DMD. It's been working since DMD1.047. Please upgrade to the latest version, you'll find it a lot less frustrating. The bottom of "function.html" in the spec gives the rules. Though it says nested functions aren't supported, but they are.
Ah, forgot about that list. Good point. But still Travis should know that the list is not exhaustive. For instance the other day I found that this didn't work for some reason: while(i < a - b) { ... } Instead I had to do int limit = a-b; while(i < limit) { ... }
I can't reproduce it. Do you have a complete test case?
Doh! Now I can't either. Maybe it was just a typo that I didn't notice. How about C functions? Any chance those'll ever work? Particularly C stdlib functions. They're one of the major things I'm finding prevents std.string functions from being used CTFE.
I don't think it could ever work. CTFE needs to have the source available. If we really needed to, a few C stdlib functions could be made into CTFE intrinsics. But in general, no. Some form of if(__ctfe) will happen, though.
Nov 17 2009
parent Kuba Ober <kuba mareimbrium.org> writes:
Don wrote:
 Bill Baxter wrote:
 On Tue, Nov 17, 2009 at 4:17 AM, Don <nospam nospam.com> wrote:
 Bill Baxter wrote:
 On Tue, Nov 17, 2009 at 2:07 AM, Don <nospam nospam.com> wrote:
 Travis Boucher wrote:
 I've been playing with string mixins, and they are very powerful.

 One thing I can't figure out is what exactly can and cannot be 
 evaluated
 at compile time.
How about C functions? Any chance those'll ever work? Particularly C stdlib functions. They're one of the major things I'm finding prevents std.string functions from being used CTFE.
I don't think it could ever work. CTFE needs to have the source available. If we really needed to, a few C stdlib functions could be made into CTFE intrinsics. But in general, no. Some form of if(__ctfe) will happen, though.
What about having compile-time access to dynamic libraries, implemented via dlopen() etc? Basically a compile-time FFI? There's nothing fundamentally unkosher about that, or so it seems to me. It would certainly be a big jaw-dropper feature for a C-like language. LISP has it, right? :) Cheers, Kuba
Nov 27 2009