digitalmars.D.learn - At compile time
- bearophile (38/38) Aug 04 2009 D2 is now able to execute math functions (sin, cos, sqrt, etc) at compil...
- Jarrett Billingsley (8/44) Aug 04 2009 (c) {}
- bearophile (6/8) Aug 04 2009 I see. It's a significant limitation, that curiously G++ doesn't share.
- Jarrett Billingsley (10/14) Aug 04 2009 I don't think your C++ code is doing what you think it's doing. I'm
- bearophile (8/11) Aug 05 2009 I see. I have to learn more about C++. Thank you.
- Ary Borenszweig (4/17) Aug 05 2009 It would be nice if the compiler could say so: "I can't evaluate it
- Jarrett Billingsley (9/34) Aug 05 2009 st..
- Don (3/27) Aug 06 2009 Nice error messages for CTFE assignment statements are in the next
- BCS (4/7) Aug 05 2009 Replying to two different post in the same post significantly reduces th...
- Don (3/9) Aug 05 2009 In fact the D1 compiler should support it too.
- Lars T. Kyllingstad (6/16) Aug 05 2009 This is good news! The restrictions you are referring to, are they any
- Don (3/25) Aug 21 2009 Both. Using CTFE will be a completely different experience after the
- Lars T. Kyllingstad (3/29) Aug 21 2009 I can't wait. :)
- bearophile (50/51) Aug 21 2009 What kind of limits do you want to lift? :-)
- Don (9/13) Aug 24 2009 The unpredictability, mainly. Currently, it's really easy to write code
- div0 (42/70) Aug 05 2009 -----BEGIN PGP SIGNED MESSAGE-----
- Sergey Gromov (28/52) Aug 05 2009 You can't call methods at compile time, and you can't pass temporary by
D2 is now able to execute math functions (sin, cos, sqrt, etc) at compile time. This little C++ program compiles correctly with G++: // C++ code #include <math.h> #include <stdio.h> struct V3 { double x, y, z; V3(const double a, const double b, const double c) : x(a), y(b), z(c) {} V3 operator*(const double d) const { return V3(x * d, y * d, z * d); } V3 norm() const { return *this * (1.0 / sqrt(magsqr())); } double dot(const V3 &v) const { return x * v.x+y * v.y + z * v.z; } double magsqr() const { return dot(*this); } }; const V3 v(V3(-0.5, -0.65, 0.9).norm()); int main() { printf("%f %f %f\n", v.x, v.y, v.z); return 0; } But similar D2 program produces, with DMD v.2.031: test.d(12): Error: non-constant expression (V3(1,2,3)).norm() // D2 code import std.math, std.c.stdio; struct V3 { double x, y, z; V3 opMul(double d) { return V3(x * d, y * d, z * d); } V3 norm() { return this * (1.0 / sqrt(this.magsqr())); } double dot(ref V3 v) { return x * v.x+y * v.y + z * v.z; } double magsqr() { return dot(this); } } const V3 v = V3(1.0, 2.0, 3.0).norm(); int main() { printf("%f %f %f\n", v.x, v.y, v.z); return 0; } Do you know why? Can the D2 compiler modified/improved to allow this? Bye and thank you, bearophile
Aug 04 2009
On Tue, Aug 4, 2009 at 7:57 PM, bearophile<bearophileHUGS lycos.com> wrote:D2 is now able to execute math functions (sin, cos, sqrt, etc) at compile=time.This little C++ program compiles correctly with G++: // C++ code #include <math.h> #include <stdio.h> struct V3 { =A0 =A0double x, y, z; =A0 =A0V3(const double a, const double b, const double c) : x(a), y(b), z=(c) {}=A0 =A0V3 operator*(const double d) const { return V3(x * d, y * d, z * d=); }=A0 =A0V3 norm() const { return *this * (1.0 / sqrt(magsqr())); } =A0 =A0double dot(const V3 &v) const { return x * v.x+y * v.y + z * v.z; =}=A0 =A0double magsqr() const { return dot(*this); } }; const V3 v(V3(-0.5, -0.65, 0.9).norm()); int main() { =A0 =A0printf("%f %f %f\n", v.x, v.y, v.z); =A0 =A0return 0; } But similar D2 program produces, with DMD v.2.031: test.d(12): Error: non-constant expression (V3(1,2,3)).norm() // D2 code import std.math, std.c.stdio; struct V3 { =A0 =A0double x, y, z; =A0 =A0V3 opMul(double d) { return V3(x * d, y * d, z * d); } =A0 =A0V3 norm() { return this * (1.0 / sqrt(this.magsqr())); } =A0 =A0double dot(ref V3 v) { return x * v.x+y * v.y + z * v.z; } =A0 =A0double magsqr() { return dot(this); } } const V3 v =3D V3(1.0, 2.0, 3.0).norm(); int main() { =A0 =A0printf("%f %f %f\n", v.x, v.y, v.z); =A0 =A0return 0; } Do you know why?I don't think you can call struct methods at compile-time. Kind of lame, I know. Try making norm a free function.Can the D2 compiler modified/improved to allow this?It sure would be nice.
Aug 04 2009
Jarrett Billingsley:I don't think you can call struct methods at compile-time. Kind of lame, I know. Try making norm a free function.I see. It's a significant limitation, that curiously G++ doesn't share. I have tried to follow your suggestion, but so far with not too much luck, even essentially pulling out all methods of that struct :-) Thank you, bye, bearophile
Aug 04 2009
On Tue, Aug 4, 2009 at 10:13 PM, bearophile<bearophileHUGS lycos.com> wrote= :Jarrett Billingsley:I don't think your C++ code is doing what you think it's doing. I'm pretty sure the C++ code: const V3 v(V3(-0.5, -0.65, 0.9).norm()); is equivalent to the following D code: const V3 v; static this() { v =3D V3(-0.5, -0.65, 0.9).norm(); } C++ has static initialization that occurs before main() too. It's just.. hidden.I don't think you can call struct methods at compile-time. =A0Kind of lame, I know. =A0Try making norm a free function.I see. It's a significant limitation, that curiously G++ doesn't share.
Aug 04 2009
Jarrett Billingsley:C++ has static initialization that occurs before main() too. It's just.. hidden.<I see. I have to learn more about C++. Thank you. ------------------ Lars T. Kyllingstad:This is good news! The restrictions you are referring to, are they any of the ones documented here: http://www.digitalmars.com/d/2.0/function.html#interpretation <That list has a point regarding what I was trying to do:4. the function may not be a non-static member, i.e. it may not have a this pointer<It's true regarding stucts used as values too, and not just classes... Bye, bearophile
Aug 05 2009
bearophile escribió:Jarrett Billingsley:It would be nice if the compiler could say so: "I can't evaluate it because you are using a this pointer". With other words, but much more useful than "non-constant expression".C++ has static initialization that occurs before main() too. It's just.. hidden.<I see. I have to learn more about C++. Thank you. ------------------ Lars T. Kyllingstad:This is good news! The restrictions you are referring to, are they any of the ones documented here: http://www.digitalmars.com/d/2.0/function.html#interpretation <That list has a point regarding what I was trying to do:4. the function may not be a non-static member, i.e. it may not have a this pointer<It's true regarding stucts used as values too, and not just classes...
Aug 05 2009
*On Wed, Aug 5, 2009 at 7:23 AM, Ary Borenszweig<ary esperanto.org.ar> wrot= e:bearophile escribi=F3:st..Jarrett Billingsley:C++ has static initialization that occurs before main() too. =A0It's ju=ofhidden.<I see. I have to learn more about C++. Thank you. ------------------ Lars T. Kyllingstad:This is good news! The restrictions you are referring to, are they any =seIt would be nice if the compiler could say so: "I can't evaluate it becau=the ones documented here: http://www.digitalmars.com/d/2.0/function.html#interpretation <That list has a point regarding what I was trying to do:4. the function may not be a non-static member, i.e. it may not have a this pointer<It's true regarding stucts used as values too, and not just classes...you are using a this pointer". With other words, but much more useful tha=n"non-constant expression".Yes, oh my God, this is the main reason I don't use CTFE: debugging them is virtually impossible, and the compiler does nothing to help there.
Aug 05 2009
Jarrett Billingsley wrote:*On Wed, Aug 5, 2009 at 7:23 AM, Ary Borenszweig<ary esperanto.org.ar> wrote:Nice error messages for CTFE assignment statements are in the next release. That's probably 50% of the instances of "non-constant expression".bearophile escribió:Yes, oh my God, this is the main reason I don't use CTFE: debugging them is virtually impossible, and the compiler does nothing to help there.Jarrett Billingsley:It would be nice if the compiler could say so: "I can't evaluate it because you are using a this pointer". With other words, but much more useful than "non-constant expression".C++ has static initialization that occurs before main() too. It's just.. hidden.<I see. I have to learn more about C++. Thank you. ------------------ Lars T. Kyllingstad:This is good news! The restrictions you are referring to, are they any of the ones documented here: http://www.digitalmars.com/d/2.0/function.html#interpretation <That list has a point regarding what I was trying to do:4. the function may not be a non-static member, i.e. it may not have a this pointer<It's true regarding stucts used as values too, and not just classes...
Aug 06 2009
Reply to bearophile,Jarrett Billingsley:[...]------------------ Lars T. Kyllingstad:Replying to two different post in the same post significantly reduces the changes that the second poster will see your reply.
Aug 05 2009
Jarrett Billingsley wrote:I don't think you can call struct methods at compile-time. Kind of lame, I know. Try making norm a free function.In fact the D1 compiler should support it too. BTW a few of the restrictions on CTFE will be removed in the next release.Can the D2 compiler modified/improved to allow this?It sure would be nice.
Aug 05 2009
Don wrote:Jarrett Billingsley wrote:This is good news! The restrictions you are referring to, are they any of the ones documented here: http://www.digitalmars.com/d/2.0/function.html#interpretation or are they "undocumented" restrictions, i.e. bugs? -LarsI don't think you can call struct methods at compile-time. Kind of lame, I know. Try making norm a free function.In fact the D1 compiler should support it too. BTW a few of the restrictions on CTFE will be removed in the next release.Can the D2 compiler modified/improved to allow this?It sure would be nice.
Aug 05 2009
Lars T. Kyllingstad wrote:Don wrote:Both. Using CTFE will be a completely different experience after the next release.Jarrett Billingsley wrote:This is good news! The restrictions you are referring to, are they any of the ones documented here: http://www.digitalmars.com/d/2.0/function.html#interpretation or are they "undocumented" restrictions, i.e. bugs? -LarsI don't think you can call struct methods at compile-time. Kind of lame, I know. Try making norm a free function.In fact the D1 compiler should support it too. BTW a few of the restrictions on CTFE will be removed in the next release.Can the D2 compiler modified/improved to allow this?It sure would be nice.
Aug 21 2009
Don wrote:Lars T. Kyllingstad wrote:I can't wait. :) -LarsDon wrote:Both. Using CTFE will be a completely different experience after the next release.Jarrett Billingsley wrote:This is good news! The restrictions you are referring to, are they any of the ones documented here: http://www.digitalmars.com/d/2.0/function.html#interpretation or are they "undocumented" restrictions, i.e. bugs? -LarsI don't think you can call struct methods at compile-time. Kind of lame, I know. Try making norm a free function.In fact the D1 compiler should support it too. BTW a few of the restrictions on CTFE will be removed in the next release.Can the D2 compiler modified/improved to allow this?It sure would be nice.
Aug 21 2009
Don:Using CTFE will be a completely different experience after the next release.<What kind of limits do you want to lift? :-) I think now LDC uses a compile-time garbage collector (beside the second one in the D runtime and the third one used by LLVM), so using CTFE&templates is better already with LDC. I like to use CTFE is to create 1D arrays at compile-time. This is a small test, it has the problem of being "fragile": if you change this code just a bit, it doesn't compile anymore. The other problem (with DMD) is that it uses a lot of RAM, even for modern standards of memory. import std.stdio: writefln; bool isPrime(int n) { if (n < 2) return false; for (int i = 2; i < n; i++) if (n % i == 0) return false; return true; } int[] genPrimes(int n) { int[] result; for (; n > 1; --n) if (isPrime(n)) result = n ~ result; return result; } static const auto primes = cast(int[900])genPrimes(7000); void main() { writefln(primes); } Currently to do such things I use templat: http://www.fantascienza.net/leonardo/so/templat.html With code like this, that's fast and uses small resources, but forces to use two languages: import std.stdio: writefln; {{ import textwrap def find_primes(n): if n < 2: return [] primes = [2] for i in xrange(2, n+1): for j in primes: if i % j == 0: break else: primes.append(i) return primes p = find_primes(7000) out = "const int primes[%d] = %s;" % (len(p), p) print "\n".join(textwrap.wrap(out, 80, subsequent_indent=" "*4)) }} void main() { writefln(primes); } Bye, bearophile
Aug 21 2009
bearophile wrote:Don:The unpredictability, mainly. Currently, it's really easy to write code that you'd expect would work in CTFE, but doesn't. Sometimes because of bugs, sometimes because of the official restrictions in the list, which are more restrictive than you'd expect. All kinds of crazy stuff is now working in my patched version of DMD. There's no improvements to the memory situation, though. That requires significant changes to several parts of the compiler. So the two most important CTFE bugs (1330 and 1382) won't be fixed in this release.Using CTFE will be a completely different experience after the next release.<What kind of limits do you want to lift? :-)
Aug 24 2009
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 bearophile wrote:D2 is now able to execute math functions (sin, cos, sqrt, etc) at compile time. This little C++ program compiles correctly with G++: // C++ code #include <math.h> #include <stdio.h> struct V3 { double x, y, z; V3(const double a, const double b, const double c) : x(a), y(b), z(c) {} V3 operator*(const double d) const { return V3(x * d, y * d, z * d); } V3 norm() const { return *this * (1.0 / sqrt(magsqr())); } double dot(const V3 &v) const { return x * v.x+y * v.y + z * v.z; } double magsqr() const { return dot(*this); } }; const V3 v(V3(-0.5, -0.65, 0.9).norm()); int main() { printf("%f %f %f\n", v.x, v.y, v.z); return 0; }<snip>Do you know why? Can the D2 compiler modified/improved to allow this? Bye and thank you, bearophileNot really relevant to the compile time issue but, your d2 code should be: import std.math; import std.stdio; struct V3 { double x, y, z; this(double _x, double _y, double _z) { x = _x; y = _y; z = _z; } V3 opMul(double d) const { return V3(x * d, y * d, z * d); } V3 norm() const { return this * (1.0 / sqrt(this.magsqr())); } double dot(ref V3 v) const { return x * v.x+y * v.y + z * v.z; } double magsqr() const { return dot(this); } } const V3 v; static this() { v = V3(1.0, 2.0, 3.0).norm(); } int main() { writefln("%f %f %f", v.x, v.y, v.z); writefln("%f", v.magsqr()); return 0; } This produces identical behavior to the c++ example. As Jarrett said, in c++ you have hidden runtime initialisation, which is made explicit in D. Having it work at compile time would be sweet. - -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iD8DBQFKed78T9LetA9XoXwRApwgAJ9Ut0GNbpDndlv5hbqFrGI0sT8PfwCgq2YQ C/C4nKF1U8ybh/nI4TBNqZk= =coIo -----END PGP SIGNATURE-----
Aug 05 2009
Tue, 04 Aug 2009 19:57:19 -0400, bearophile wrote:D2 is now able to execute math functions (sin, cos, sqrt, etc) at compile time. [snip] But similar D2 program produces, with DMD v.2.031: test.d(12): Error: non-constant expression (V3(1,2,3)).norm() // D2 code import std.math, std.c.stdio; struct V3 { double x, y, z; V3 opMul(double d) { return V3(x * d, y * d, z * d); } V3 norm() { return this * (1.0 / sqrt(this.magsqr())); } double dot(ref V3 v) { return x * v.x+y * v.y + z * v.z; } double magsqr() { return dot(this); } } const V3 v = V3(1.0, 2.0, 3.0).norm(); int main() { printf("%f %f %f\n", v.x, v.y, v.z); return 0; }You can't call methods at compile time, and you can't pass temporary by reference. This works: import std.math, std.c.stdio; struct V3 { double x, y, z; V3 opMul(double d) { return V3(x * d, y * d, z * d); } V3 norm() { return this * (1.0 / sqrt(this.magsqr())); } double dot(ref V3 v) { return x * v.x+y * v.y + z * v.z; } double magsqr() { return dot(this); } } V3 mul(ref V3 v, double d) { return V3(v.x*d, v.y*d, v.z*d); } V3 norm(V3 v) { return mul(v, 1.0 / sqrt(magsqr(v))); } double dot(ref V3 a, ref V3 b) { return a.x*b.x + a.y*b.y + a.z*b.z; } double magsqr(ref V3 v) { return dot(v, v); } const V3 v = norm(V3(1.0, 2.0, 3.0)); int main() { printf("%f %f %f\n", v.x, v.y, v.z); return 0; }
Aug 05 2009