digitalmars.D - What the heck is wrong with CTFE's?
- JS (41/41) Jul 08 2013 The following code inserts properties for each type,
- JS (3/9) Jul 08 2013 this is a mistake, I'm not sure what's going on, i seems to
- JS (7/20) Jul 08 2013 sheit... sorry, stupid mistake..
- Dicebot (5/10) Jul 08 2013 Because i is not a compile-time value, it is a normal variable.
- JS (50/60) Jul 08 2013 This has nothing to do with it...
- JS (9/9) Jul 08 2013 Ultimately, the point is, that I thought CTFE's were suppose to
- Marco Leise (14/23) Jul 08 2013 If you look through the thread, others said that the behavoir
- Artur Skawina (8/27) Jul 08 2013 What should the following program print?
- John Colvin (5/22) Jul 08 2013 This will never increment i, whether in ctfe or at runtime. The
- JS (2/29) Jul 08 2013
- Dicebot (11/12) Jul 08 2013 CTFE has nothing to do with it.
- Dicebot (1/1) Jul 08 2013 P.S. you speak about (i == 0) but your snippet has (i > 0)
- JS (23/24) Jul 08 2013 Thats simply because I forgot to change it.. I tried various
- Dicebot (6/6) Jul 08 2013 Hello there. Have you read my answer? The very first one?
- John Colvin (3/15) Jul 08 2013 Nothing wrong with that. It's the normal behaviour in C, and it
- John Colvin (26/67) Jul 08 2013 after weeding out the bugs and unusual things, plus letting
- John Colvin (5/7) Jul 08 2013 Scratch that, there's nothing surprising about it at all. i == 0
The following code inserts properties for each type, auto name = "Value"~((i == 0) ? "" : to!string(i++)); always as the i == 0 evaluate to true. My question is, why the heck is it so hard to use basic programming structs inside CTFE's? I know that CTFE's have to work at run time also, so there is a limitation, but: 1. obviously ints work because the code below works with i as a counter but we can't do a simple compare on it... this seems like a bug. 2. foreach can be used but a simple for loop can't... makes no sense. I know what the average response is going to be but hopefully someone will surprise me with some useful. mixin template PropertyBuilder(T...) { template _(TT...) { static string eval() { string s; pragma(msg, TT); int i = 0; foreach(t; TT) { auto name = "Value"~((i > 0) ? "" : to!string(i++)); s = " property "~t.stringof~" "~name~"();\n"; s ~=" property "~t.stringof~" "~name~"("~t.stringof~" value);\n"; } return s; } enum _ = eval(); pragma(msg, _); } mixin("mixin(_!T);"); } interface a(MT...) { mixin PropertyBuilder!MT; }
Jul 08 2013
On Monday, 8 July 2013 at 11:56:40 UTC, JS wrote:The following code inserts properties for each type, auto name = "Value"~((i == 0) ? "" : to!string(i++)); always as the i == 0 evaluate to true. 1. obviously ints work because the code below works with i as a counter but we can't do a simple compare on it... this seems like a bug.this is a mistake, I'm not sure what's going on, i seems to increment but name always seems to evaluate to the largest i.
Jul 08 2013
On Monday, 8 July 2013 at 12:03:52 UTC, JS wrote:On Monday, 8 July 2013 at 11:56:40 UTC, JS wrote:sheit... sorry, stupid mistake.. the issue with the foreach is still under question though, when I try to use a for loop with i and access TT[i] I get an error about i not being compile time readable. (maybe this is because of how the type tuple is defined? possibly need a index method to get the value?)The following code inserts properties for each type, auto name = "Value"~((i == 0) ? "" : to!string(i++)); always as the i == 0 evaluate to true. 1. obviously ints work because the code below works with i as a counter but we can't do a simple compare on it... this seems like a bug.this is a mistake, I'm not sure what's going on, i seems to increment but name always seems to evaluate to the largest i.
Jul 08 2013
On Monday, 8 July 2013 at 12:08:44 UTC, JS wrote:the issue with the foreach is still under question though, when I try to use a for loop with i and access TT[i] I get an error about i not being compile time readable. (maybe this is because of how the type tuple is defined? possibly need a index method to get the value?)Because i is not a compile-time value, it is a normal variable. And TT is a type tuple, pure compile-time entity. You really need to study the documentation on this topic or frustration will continue.
Jul 08 2013
On Monday, 8 July 2013 at 12:11:36 UTC, Dicebot wrote:On Monday, 8 July 2013 at 12:08:44 UTC, JS wrote:This has nothing to do with it... string name = "Value"~((i==0) ? "" : (to!string(i))); i++; works, but string name = "Value"~((i==0) ? "" : (to!string(i++))); but doesn't.... It is a matter of placement of the increment operation on i that is breaking the code and has nothing to do with your default answer of "you don't know how CTFE's work, read the docs!" and "... it's not a compile-time variable". If i's not possible to use at compile time then none of the following code examples should work One could argue that depending on how to!string works could be the issue, but this has nothing to do with i, which is what you have stated, but to!string. If it is to!string or templates in general that are the issue then it is confusing to have the same syntax for compile time and runtime but some common runtime syntax doesn't work. e.g., int x = 0; writeln(x); to!string(x++); writeln(x); works fine at run-time, but to!string(i++) fails and to!string(i); i++; works in CTFE... So, either this is what you were getting at but didn't explain it well(making the issue about i when it is about CTFE templates) or you didn't understand the issue yourself. int i = 0; foreach(t; T) { string name = "Value"~((i==0) ? "" : (to!string(i))); i++; } vs int i = 0; foreach(t; T) { string name = "Value"~((i==0) ? "" : (to!string(i++))); } vs foreach(i, t; T) { string name = "Value"~((i==0) ? "" : (to!string(i))); } all are suppose to do the same thing and are all essentially semantically identical... they should do the same. (at least according to your logic and the compiler error message that says the issue is with i)the issue with the foreach is still under question though, when I try to use a for loop with i and access TT[i] I get an error about i not being compile time readable. (maybe this is because of how the type tuple is defined? possibly need a index method to get the value?)Because i is not a compile-time value, it is a normal variable. And TT is a type tuple, pure compile-time entity. You really need to study the documentation on this topic or frustration will continue.
Jul 08 2013
Ultimately, the point is, that I thought CTFE's were suppose to be compile time runnable functions. The problem is, the actual language grammar changes. can use i++ as an argument to a template at runtime without issue but not at compile time... and since this seems to be the case from the examples I've posted, this causes, at least for me, a lot of confusion. (who knows what other differences there are) (and IMO they are flaws in the CTFE system... although maybe there is some deep underlying reason why it must be done that way)
Jul 08 2013
Am Tue, 09 Jul 2013 01:02:12 +0200 schrieb "JS" <js.mdnq gmail.com>:Ultimately, the point is, that I thought CTFE's were suppose to be compile time runnable functions. The problem is, the actual language grammar changes. can use i++ as an argument to a template at runtime without issue but not at compile time... and since this seems to be the case from the examples I've posted, this causes, at least for me, a lot of confusion. (who knows what other differences there are) (and IMO they are flaws in the CTFE system... although maybe there is some deep underlying reason why it must be done that way)If you look through the thread, others said that the behavoir is the same in C at runtime. Your use of the ternary operator is the problem. Only the branch that is taken is executed. This should be obvious, but I agree that when the other branch contains an i++ it looks like it should be executed. Please look at the ternary operator as an if and else and it will become clear why your increment works when you put it on a separate line. TL;DR: It has nothing to do with flaws in D or CTFE. At least not this time around. ;) -- Marco
Jul 08 2013
On 07/09/13 00:57, JS wrote:On Monday, 8 July 2013 at 12:11:36 UTC, Dicebot wrote:What should the following program print? void main() { import std.stdio; auto a = 0; a==0 ? writeln("Hello") : writeln("world!"); } arturOn Monday, 8 July 2013 at 12:08:44 UTC, JS wrote:This has nothing to do with it... string name = "Value"~((i==0) ? "" : (to!string(i))); i++; works, but string name = "Value"~((i==0) ? "" : (to!string(i++))); but doesn't.... It is a matter of placement of the increment operation on i that is breaking the code and has nothing to do with your default answer of "you don't know how CTFE's work, read the docs!" and "... it's not a compile-time variable".the issue with the foreach is still under question though, when I try to use a for loop with i and access TT[i] I get an error about i not being compile time readable. (maybe this is because of how the type tuple is defined? possibly need a index method to get the value?)Because i is not a compile-time value, it is a normal variable. And TT is a type tuple, pure compile-time entity. You really need to study the documentation on this topic or frustration will continue.
Jul 08 2013
On Monday, 8 July 2013 at 22:57:17 UTC, JS wrote:int i = 0; foreach(t; T) { string name = "Value"~((i==0) ? "" : (to!string(i))); i++; }That increments i, both ctfe and rt.vs int i = 0; foreach(t; T) { string name = "Value"~((i==0) ? "" : (to!string(i++))); }This will never increment i, whether in ctfe or at runtime. The entire "(to!string(i++))" will never be executed.vs foreach(i, t; T) { string name = "Value"~((i==0) ? "" : (to!string(i))); }This will increment i, both in ctfe and at runtime.
Jul 08 2013
On Monday, 8 July 2013 at 23:36:46 UTC, John Colvin wrote:On Monday, 8 July 2013 at 22:57:17 UTC, JS wrote:oh shit! lol... fuck I'm stupid! ;/int i = 0; foreach(t; T) { string name = "Value"~((i==0) ? "" : (to!string(i))); i++; }That increments i, both ctfe and rt.vs int i = 0; foreach(t; T) { string name = "Value"~((i==0) ? "" : (to!string(i++))); }This will never increment i, whether in ctfe or at runtime. The entire "(to!string(i++))" will never be executed.vs foreach(i, t; T) { string name = "Value"~((i==0) ? "" : (to!string(i))); }This will increment i, both in ctfe and at runtime.
Jul 08 2013
On Monday, 8 July 2013 at 11:56:40 UTC, JS wrote:...CTFE has nothing to do with it. void main() { import std.stdio; int i = 0; writeln(i == 0 ? i : i++); writeln(i); } "i++" is evaluated lazy here. I don't know if it is a bug or matches the spec.
Jul 08 2013
P.S. you speak about (i == 0) but your snippet has (i > 0)
Jul 08 2013
On Monday, 8 July 2013 at 12:09:55 UTC, Dicebot wrote:P.S. you speak about (i == 0) but your snippet has (i > 0)Thats simply because I forgot to change it.. I tried various things... it's not relevant... the problem is back... when I remove the compare on i name is updated, when I don' t it isn't: string name = "Value"~((i == 0) ? "" : to!string(i++)); } produces property int Value(); property int Value(int value); property double Value(); property double Value(double value); property long Value(); property long Value(long value); but string name = "Value"~(to!string(i++)); property int Value0(); property int Value0(int value); property double Value1(); property double Value1(double value); property long Value2(); property long Value2(long value); so the original statement was correct about i==0.
Jul 08 2013
Hello there. Have you read my answer? The very first one? 1) i will never be incremented there and CTFE has nothing to do with it. 2) This topic should have been in D.learn 3) If you won't tone down your arrogance, soon there will be no one left willing to answer you.
Jul 08 2013
On Monday, 8 July 2013 at 12:08:39 UTC, Dicebot wrote:On Monday, 8 July 2013 at 11:56:40 UTC, JS wrote:Nothing wrong with that. It's the normal behaviour in C, and it makes perfect sense if you just expand the ternary out to if/else....CTFE has nothing to do with it. void main() { import std.stdio; int i = 0; writeln(i == 0 ? i : i++); writeln(i); } "i++" is evaluated lazy here. I don't know if it is a bug or matches the spec.
Jul 08 2013
On Monday, 8 July 2013 at 11:56:40 UTC, JS wrote:The following code inserts properties for each type, auto name = "Value"~((i == 0) ? "" : to!string(i++)); always as the i == 0 evaluate to true. My question is, why the heck is it so hard to use basic programming structs inside CTFE's? I know that CTFE's have to work at run time also, so there is a limitation, but: 1. obviously ints work because the code below works with i as a counter but we can't do a simple compare on it... this seems like a bug. 2. foreach can be used but a simple for loop can't... makes no sense. I know what the average response is going to be but hopefully someone will surprise me with some useful. mixin template PropertyBuilder(T...) { template _(TT...) { static string eval() { string s; pragma(msg, TT); int i = 0; foreach(t; TT) { auto name = "Value"~((i > 0) ? "" : to!string(i++)); s = " property "~t.stringof~" "~name~"();\n"; s ~=" property "~t.stringof~" "~name~"("~t.stringof~" value);\n"; } return s; } enum _ = eval(); pragma(msg, _); } mixin("mixin(_!T);"); } interface a(MT...) { mixin PropertyBuilder!MT; }after weeding out the bugs and unusual things, plus letting foreach manage i: mixin template PropertyBuilder(T...) { template _(TT...) { static string eval() { string s; foreach(i, t; TT) { auto name = "Value"~((i > 0) ? to!string(i) : ""); s ~= " property "~t.stringof~" "~name~"();\n"; s ~=" property void "~name~"("~t.stringof~" value);\n"; } return s; } enum _ = eval(); } mixin("mixin(_!T);"); } which works fine. The i++ in to!string not having any effect is rather surprising, I agree.
Jul 08 2013
On Monday, 8 July 2013 at 12:41:22 UTC, John Colvin wrote:The i++ in to!string not having any effect is rather surprising, I agree.Scratch that, there's nothing surprising about it at all. i == 0 on the first iteration and therefore the first branch of the ternary isn't executed. The same thing happens the next iteration and so on, leaving i==0 for every iteration.
Jul 08 2013