www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Stefan Koch: New CTFE fix

reply Johnson Jones <JJ Dynomite.com> writes:
Hi Stefan,

I have a suggestion/request for you for newCTFE:

string do()
{
    string x;
    x = "adsf";
    pragma(msg, x);
    return x;
}

fails because the compiler believes that x is not known at 
compile time. It obviously is when do is ran as a ctfe. This 
makes some types of programming difficult to debug because we 
have to duplicate any instance of "do" and cannot output 
intermediate values.

But, how can we make this actually work?

One way may be to treat all strings as enums internally and allow 
normal string operations on them, effectively creating a 
string_enum type.

In fact, maybe a new type would be the easiest way. string_enum 
is a string at runtime but an enum with string operations at 
compile time. (for memory efficiency they could be more like 
string builders)


Another possible way is for the compiler to emit the pragma(msg, 
x) as sort of writelns. i.e., ctfe_writeln, which if I recall, 
hasn't been added yet.

Then we end up something like

string do()
{
    string x;
    x = "adsf";
    ctfe_writeln(x);
    return x;
}

which either could immediately display x if possible, or the 
compiler could collect all output then display after the function 
is called(issues are that errors might break the output).

I'm sure other solutions are possible. pragma(msg, ) could act 
different depending on if it is use on a variable that is used 
inside a ctfe vs a compile time "variable" used inside a ctfe.

Maybe your newCTFE already has the ability to do this or make it 
easy? It would surely help me because I tend to use a lot of 
mixins and generally cannot easily output the results for 
debugging purposes(and since mixins already are nearly impossible 
to debug like normal code, we need something useful to help us 
out).
Aug 14
parent reply Moritz Maxeiner <moritz ucworks.org> writes:
On Monday, 14 August 2017 at 22:51:04 UTC, Johnson Jones wrote:
 string do()
 {
    string x;
    x = "adsf";
    pragma(msg, x);
    return x;
 }
"do" is a keyword in D, you can't use it as an identifier.
 fails because the compiler believes that x is not known at 
 compile time.
There are multiple phases making up D's compile time, the wiki has an excellent page by H. S. Teoh on the subject [1]. Applied to your example: The pragma in the function body is handled before the function body is interpreted, so the compiler error is correct; whether or not the error message should be more explicit is another matter.
 It obviously is when do is ran as a ctfe. This makes some types 
 of programming difficult to debug because we have to duplicate 
 any instance of "do" and cannot output intermediate values.

 But, how can we make this actually work?

 [...]
I recommend reading up on the history of CTFE output in D[2][3][4][5][6]. If you want to see CTFE output in D, you could pick up where Stefan left off in the latest attempt[6]. [1] https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time [2] http://www.digitalmars.com/d/archives/digitalmars/D/CTFE_writeln_140241.html [3] http://forum.dlang.org/thread/j1n0l7$235r$1 digitalmars.com [4] https://github.com/dlang/dmd/pull/296 [5] https://github.com/dlang/dmd/pull/692 [6] https://github.com/dlang/dmd/pull/6101
Aug 14
parent reply Johnson <Johnson Johnson.com> writes:
On Tuesday, 15 August 2017 at 01:31:13 UTC, Moritz Maxeiner wrote:
 On Monday, 14 August 2017 at 22:51:04 UTC, Johnson Jones wrote:
 string do()
 {
    string x;
    x = "adsf";
    pragma(msg, x);
    return x;
 }
"do" is a keyword in D, you can't use it as an identifier.
wow, way to fail to realize generalities.
 fails because the compiler believes that x is not known at 
 compile time.
There are multiple phases making up D's compile time, the wiki has an excellent page by H. S. Teoh on the subject [1]. Applied to your example: The pragma in the function body is handled before the function body is interpreted, so the compiler error is correct; whether or not the error message should be more explicit is another matter.
So, that is a generic answer for a generic post. It says nothing about what can be done, but what only can't be done. There is nothing stopping one's ability to output compile time information at compile time from compile time functions. Again, way to fail to realize generalities. Just because something is defined to be something doesn't mean that it can't be defined to be something different. It happens all the time. People create false constraints based on ignorance and then someone has to come along and clean up the mess. But some people like messes I suppose...
 It obviously is when do is ran as a ctfe. This makes some 
 types of programming difficult to debug because we have to 
 duplicate any instance of "do" and cannot output intermediate 
 values.

 But, how can we make this actually work?

 [...]
I recommend reading up on the history of CTFE output in D[2][3][4][5][6]. If you want to see CTFE output in D, you could pick up where Stefan left off in the latest attempt[6]. [1] https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time [2] http://www.digitalmars.com/d/archives/digitalmars/D/CTFE_writeln_140241.html [3] http://forum.dlang.org/thread/j1n0l7$235r$1 digitalmars.com [4] https://github.com/dlang/dmd/pull/296 [5] https://github.com/dlang/dmd/pull/692 [6] https://github.com/dlang/dmd/pull/6101
It seems like he's already done all the heavy lifting and who knows best rather than him to implement it in his own redesign of ctfe(to fix the mess that it was in precisely for the reasons I stated above)?
Aug 14
parent reply Moritz Maxeiner <moritz ucworks.org> writes:
On Tuesday, 15 August 2017 at 01:41:58 UTC, Johnson wrote:
 On Tuesday, 15 August 2017 at 01:31:13 UTC, Moritz Maxeiner 
 wrote:
 On Monday, 14 August 2017 at 22:51:04 UTC, Johnson Jones wrote:
 string do()
 {
    string x;
    x = "adsf";
    pragma(msg, x);
    return x;
 }
"do" is a keyword in D, you can't use it as an identifier.
wow, way to fail to realize generalities.
The failure lies on your side in not providing syntactically valid code in a discussion that's about semantics.
 fails because the compiler believes that x is not known at 
 compile time.
There are multiple phases making up D's compile time, the wiki has an excellent page by H. S. Teoh on the subject [1]. Applied to your example: The pragma in the function body is handled before the function body is interpreted, so the compiler error is correct; whether or not the error message should be more explicit is another matter.
So, that is a generic answer for a generic post. It says nothing about what can be done, but what only can't be done.
Then I have to assume you haven't read the page I linked to, since it describes the different compile time mechanics and how they interact with each other (i.e. what you can do with them).
 There is nothing stopping one's ability to output compile time 
 information at compile time from compile time functions. Again, 
 way to fail to realize generalities.
The failure lies with you being unwilling to acknownledge the different phases of compile time; specifically, that pragmas cannot access variables initialized in CTFE (__ctfeWrite can, however).
 Just because something [rant]
You are entitled to your opinion, but it's not relevant in this (technical) discussion.
 It obviously is when do is ran as a ctfe. This makes some 
 types of programming difficult to debug because we have to 
 duplicate any instance of "do" and cannot output intermediate 
 values.

 But, how can we make this actually work?

 [...]
I recommend reading up on the history of CTFE output in D[2][3][4][5][6]. If you want to see CTFE output in D, you could pick up where Stefan left off in the latest attempt[6]. [1] https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time [2] http://www.digitalmars.com/d/archives/digitalmars/D/CTFE_writeln_140241.html [3] http://forum.dlang.org/thread/j1n0l7$235r$1 digitalmars.com [4] https://github.com/dlang/dmd/pull/296 [5] https://github.com/dlang/dmd/pull/692 [6] https://github.com/dlang/dmd/pull/6101
It seems like he's already done all the heavy lifting and who knows best rather than him to implement it in his own redesign of ctfe(to fix the mess that it was in precisely for the reasons I stated above)?
newCTFE is not a redesign of the compile time architecture, it is more performant CTFE engine (Period). That being said, anyone who wants to tackle a small issue to contribute to D could've implemented __ctfeWrite. My own ~30 minute attempt (of which 25+ minutes were spent reading dmd source) is open [1]. [1] https://github.com/dlang/dmd/pull/7082
Aug 14
parent reply Johnson <Johnson Johnson.com> writes:
I'm sorry, but you are obviously someone in *need* to prove 
something. No need to respond, ever.
Aug 15
next sibling parent reply Biotronic <simen.kjaras gmail.com> writes:
On Tuesday, 15 August 2017 at 16:10:40 UTC, Johnson wrote:
 I'm sorry, but you are obviously someone in *need* to prove 
 something. No need to respond, ever.
You need to grow up. When Moritz commented on your use of 'do' as a function name, that may have been unnecessary for a discussion of your problem. Your vitriolic and childish reaction to that though, was not just unnecessary, but has done you a massive disservice and is more than unlikely to garner goodwill from others on the forum. Your opening post shows that you have little understanding of how the compiler works. There is nothing inherently wrong in this, but your utter failure at absorbing the information Moritz made available to you indicate you have no interest in attaining that understanding. With your hostile words and disinterest in learning, you have doomed what might have been an interesting discussion. Simply put, there are reasons why pragma(msg, x); fails in your example, and while in that specific example it would be possible[1] to change the compiler so that it would work the way you expect it to, that's not possible in the general case, and would be too much work for too little a gain to cover the cases where it's possible. Your example is obviously a toy example, so we can't really help you in figuring out how to work around the issue you may be having, but I expect enum to be of help, and that a good factoring of functions should give testable units that can then be inspected with pragma(msg). That is, until we have a functioning __ctfeWrite in druntime. The function is already in druntime's object.d, and is just awaiting an implementation[2]. That implementation will possibly have to wait for Stefan's CTFE makeover to complete. [1] But not necessarily easy. [2] https://github.com/dlang/dmd/pull/6101 -- Biotronic
Aug 16
next sibling parent reply Moritz Maxeiner <moritz ucworks.org> writes:
On Wednesday, 16 August 2017 at 07:24:36 UTC, Biotronic wrote:
 When Moritz commented on your use of 'do' as a function name, 
 that may have been unnecessary for a discussion of your problem.
I would contend that when discussing semantics (that is the PL's syntax is not open for change as part of the discussion) it's common courtesy to use valid syntax. You're right in that it was unnecessary to discuss the issue he was describing, but it was relevant to me as a matter of principle.
 That is, until we have a functioning __ctfeWrite in druntime. 
 The function is already in druntime's object.d, and is just 
 awaiting an implementation[2]. That implementation will 
 possibly have to wait for Stefan's CTFE makeover to complete.
Well, my implementation attempt I linked to earlier [1] passes the auto tester for the test in Stefan's original PR and so far it works as expected in all my personal cases. If you find something wrong with it, please comment on the PR's page :) [1] https://github.com/dlang/dmd/pull/7082
Aug 16
next sibling parent Moritz Maxeiner <moritz ucworks.org> writes:
On Wednesday, 16 August 2017 at 10:03:56 UTC, Moritz Maxeiner 
wrote:
 You're right in that it was unnecessary to discuss the issue he 
 was describing, but it was relevant to me as a matter of 
 principle.
* You're right in that it was unnecessary for discussing the issue he
 was describing
Sorry, realized too late that this was ambiguous.
Aug 16
prev sibling parent reply Johnson <Johnson Johnson.com> writes:
On Wednesday, 16 August 2017 at 10:03:56 UTC, Moritz Maxeiner 
wrote:
 On Wednesday, 16 August 2017 at 07:24:36 UTC, Biotronic wrote:
 When Moritz commented on your use of 'do' as a function name, 
 that may have been unnecessary for a discussion of your 
 problem.
I would contend that when discussing semantics (that is the PL's syntax is not open for change as part of the discussion) it's common courtesy to use valid syntax. You're right in that it was unnecessary to discuss the issue he was describing, but it was relevant to me as a matter of principle.
No, it wasn't. It was a matter of you ego... and I see your buddies have joined the game. What if I did void Do() { } Would you bitch and complain about that? Maybe the original was a syntax error then and not a "semantic" error as you like to call it? The fact is, the name of the function is completely irrelevant to the discussion and you had to make a big deal out of it because of your ego. What if it were pseudo code? Again, instead proof that either you are an idiot(which I doubt) or that you have some need to prove something and will find anything to nitpick on. This is far more childish than those morons that say I'm childish, and they even agree with me that what you did was nonsense... completely irrelevant to the discussion.
 That is, until we have a functioning __ctfeWrite in druntime. 
 The function is already in druntime's object.d, and is just 
 awaiting an implementation[2]. That implementation will 
 possibly have to wait for Stefan's CTFE makeover to complete.
Well, my implementation attempt I linked to earlier [1] passes the auto tester for the test in Stefan's original PR and so far it works as expected in all my personal cases. If you find something wrong with it, please comment on the PR's page :) [1] https://github.com/dlang/dmd/pull/7082
So, if the people already want what I want, and you already did your own pull, why the hell are you saying it can't be done? Again, because you are looking for something to prove, and calling you out on it is the right thing to do regardless what idiots think. You can make the claim that pragma(msg, ...) happens before the ctfe is ran, but again, which pragma(msg, ...)? With CTFE there are two levels, the compiler is ran twice, once on the original code and once on the CTFE to actually compile it. Just because the compiler run's it the first time DOES not mean that should be the only way. You talk about semantics but you seem not to understand the term well. A single symbolic name for something can have many interpretations. When one, someone like yourself or the D compiler, only interprets it one way, it leads to problems. How out pragmaCTFE(msg, ...)? Is that good enough for you, or you will find something wrong with that too? Do you realize that there are two levels of compilation going in with ctfe? Essentially two DMD's? If there are two dmd's then there are two pragma's, is there not? So the arguments you make may be correct, you are missing half of the equation and fail to realize that because you are trying to prove something rather than enlighten yourself.
Aug 16
parent Moritz Maxeiner <moritz ucworks.org> writes:
On Wednesday, 16 August 2017 at 13:53:40 UTC, Johnson wrote:
 On Wednesday, 16 August 2017 at 10:03:56 UTC, Moritz Maxeiner 
 wrote:
 On Wednesday, 16 August 2017 at 07:24:36 UTC, Biotronic wrote:
 When Moritz commented on your use of 'do' as a function name, 
 that may have been unnecessary for a discussion of your 
 problem.
I would contend that when discussing semantics (that is the PL's syntax is not open for change as part of the discussion) it's common courtesy to use valid syntax. You're right in that it was unnecessary to discuss the issue he was describing, but it was relevant to me as a matter of principle.
No, it wasn't.
Refer to my post clarifying that (ambiguous) sentence.
 It was a matter of you ego... and I see your buddies have 
 joined the game.
I see ad hominem attacks remain your favorite response :)
 What if I did

 void Do() { }

 Would you bitch and complain about that?
If you actually bothered to not only read my post but actually think about it, then you would realize that the answer to that question is "I neither bitched nor complained about the first one, I wouldn't about the second one, either".
 Maybe the original was a syntax error then and not a "semantic" 
 error as you like to call it?
I have not written about semantic errors so far. Regardless, yes, as I pointed out it was a syntax error.
 The fact is, the name of the function is completely irrelevant 
 to the discussion
As I pointed out, I consider it common courtesy to use valid PL syntax when discussing semantic issues. Even if I didn't, it was still an error.
 and you had to make a big deal out of it
Interesting (and frankly amusing) how you attempt to twist things around. All I did was neutrally point out the invalid syntax; the disproportionate emotional response including ad hominem attacks (also known as "making a big deal out of it") was all you.
 because of your ego.
Again with the ad hominem, also pure speculation.
 What if it were pseudo code?
Then I wouldn't have pointed it out as a syntax error. The context, however, made it quite clear it was not pseudo code :)
 Again, instead proof that either you are an idiot(which I 
 doubt) or that you have some need to prove something and will 
 find anything to nitpick on.
You emotional outburst is misplaced. If you don't want factual mistakes pointed out, refrain from engaging in technical discussions.
 This is far more childish than those morons that say I'm 
 childish,
Ad hominem.
 and they even agree with me that what you did was nonsense...
a) So far one other person has responded, not multiple b) Did you read the same post I did? Because that post wrote "may have been unnecessary", which is not the same as "was unnecessary". Even assuming that he did mean "was unnecessary" is not the same as "nonsense". Even assuming he did mean "nonsense", I already explained my reasoning.
 completely irrelevant to the discussion.
See above.
 That is, until we have a functioning __ctfeWrite in druntime. 
 The function is already in druntime's object.d, and is just 
 awaiting an implementation[2]. That implementation will 
 possibly have to wait for Stefan's CTFE makeover to complete.
Well, my implementation attempt I linked to earlier [1] passes the auto tester for the test in Stefan's original PR and so far it works as expected in all my personal cases. If you find something wrong with it, please comment on the PR's page :) [1] https://github.com/dlang/dmd/pull/7082
So, if the people already want what I want,
They don't, you *explicitly* wanted `pragma(msg, ...)` to work.
 and you already did your own pull, why the hell are you saying 
 it can't be done?
pragma(msg, ...) != __ctfeWrite Which you would know, if you actually read the compile time page by H. S. Teoh I linked you earlier :)
 Again, because you are looking for something to prove, and 
 calling you out on it is the right thing to do regardless what 
 idiots think.
Ad hominem.
 You can make the claim that pragma(msg, ...) happens before the 
 ctfe is ran, but again, which pragma(msg, ...)?
It's not a claim, it's a fact.
 With CTFE there are two levels, the compiler is ran twice, once 
 on the original code and once on the CTFE to actually compile 
 it. Just because the compiler run's it the first time DOES not 
 mean that should be the only way. You talk about semantics but 
 you seem not to understand the term well.  A single symbolic 
 name for something can have many interpretations. When one, 
 someone like yourself or the D compiler, only interprets it one 
 way, it leads to problems.
You really should read that page I linked to earlier.
 How out pragmaCTFE(msg, ...)? Is that good enough for you, or 
 you will find something wrong with that too?
Renaming pragma to pragmaCTFE doesn't change anything, because it's still a pragma and pragmas in a function body are handled before the function body is interpreted at CTFE.
 Do you realize that there are two levels of compilation going 
 in with ctfe? Essentially two DMD's? If there are two dmd's 
 then there are two pragma's, is there not? So the arguments you 
 make may be correct, you are missing half of the equation and 
 fail to realize that because you are trying to prove something 
 rather than enlighten yourself.
This is essentially a repetition of the paragraph two quotes up, combined with ad hominem.
Aug 16
prev sibling parent reply Johnson <Johnson Johnson.com> writes:
On Wednesday, 16 August 2017 at 07:24:36 UTC, Biotronic wrote:
 On Tuesday, 15 August 2017 at 16:10:40 UTC, Johnson wrote:
 I'm sorry, but you are obviously someone in *need* to prove 
 something. No need to respond, ever.
You need to grow up. When Moritz commented on your use of 'do' as a function name, that may have been unnecessary for a discussion of your problem. Your vitriolic and childish reaction to that though, was not just unnecessary, but has done you a massive disservice and is more than unlikely to garner goodwill from others on the forum.
Oh, your such a bad boy. How bout you grow up. If I'm childish, you are just a smaller child because you are doing the exact same thing... getting on the internet, pretending to be some bad boy with something to say... like anyone will listen to you. That goes for your buddy too. Probably all the same person that has nothing real to say. But at least we agree on Mortimer. You know, if you people actually focused on the real issues instead of trying to show how bit your (tiny)dick was then there would be less problems in the world.
Aug 16
next sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
On Wednesday, 16 August 2017 at 13:55:51 UTC, Johnson wrote:
 You know, if you people actually focused on the real issues ...
I agree. Please apply said focus. Reflection is not limited to compile-time.
Aug 16
prev sibling parent Olivier FAURE <olivier.faure epitech.eu> writes:
On Wednesday, 16 August 2017 at 13:55:51 UTC, Johnson wrote:
 Oh, your such a bad boy. How bout you grow up. If I'm childish, 
 you are just a smaller child because you are doing the exact 
 same thing... getting on the internet, pretending to be some 
 bad boy with something to say... like anyone will listen to 
 you. That goes for your buddy too. Probably all the same person 
 that has nothing real to say.
For what it's worth, I apologize for what I said earlier. I stand by it, but I shouldn't have called you names for the sake of it. That said, you're insulting people who are (mostly) trying to help you. This isn't a "who's right and who's wrong" thing. I'm *not* trying to smack you down or prove you're an idiot, I'm trying to help you (and, as you're no doubt thinking, I'm bored and I like drama on the internet and whatever). Don't behave like that, please. It's somewhat hurtful to other people, it ruins productive discussion, and it probably makes the discussion irritating for you too. I do agree that Moritz "do" comment was a little pedantic, and I think his next answers in this thread are barely more constructive than yours, but again, it's not a "he's wrong then you're right" thing. You could have told him off without being extremely aggressive and insulting. The fact that you did that is why Biotronic and I have been calling you "immature", not because we're all infatuated with Moritz or because we're a hive mind dedicated to being jealous of you.
Aug 17
prev sibling parent Olivier FAURE <olivier.faure epitech.eu> writes:
On Tuesday, 15 August 2017 at 16:10:40 UTC, Johnson wrote:
 I'm sorry, but you are obviously someone in *need* to prove 
 something. No need to respond, ever.
You're being extremely rude and immature.
Aug 16