www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - bug in pragma?

reply "JS" <js.mdnq gmail.com> writes:
import std.stdio, std.cstream;


template test(alias x)
{
	string func()
	{
		string s = "beta";
		//pragma(msg, s);
		return s;
	}
	enum test = func();
}

void main(string[] args)
{
	mixin test!("alpha");
	din.getc();
}

When I try to display a compiler msg using pragma on a string 
variable the mixin fails. Commenting out the pragma allows the 
mixin to work.

While there may be some internal reason this shouldn't work it 
seems quite unnatural and took me a while to figure out it was 
pragma causing the problem in my code.
Jul 04 2013
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, July 05, 2013 00:29:20 JS wrote:
 import std.stdio, std.cstream;
 
 
 template test(alias x)
 {
 	string func()
 	{
 		string s = "beta";
 		//pragma(msg, s);
 		return s;
 	}
 	enum test = func();
 }
 
 void main(string[] args)
 {
 	mixin test!("alpha");
 	din.getc();
 }
 
 When I try to display a compiler msg using pragma on a string
 variable the mixin fails. Commenting out the pragma allows the
 mixin to work.
 
 While there may be some internal reason this shouldn't work it
 seems quite unnatural and took me a while to figure out it was
 pragma causing the problem in my code.
I wouldn't ever expect that pragma to work. pramga is a compile-time construct and requires compile-time arguments, whereas s is normal, local variable and not usable at compile-time except when the function it's in is called as part of CTFE. It would work if s were an enum, because the value of an enum must be known at compile time, but that's not the case with a normal string variable. - Jonathan M Davis
Jul 04 2013
parent reply "JS" <js.mdnq gmail.com> writes:
On Thursday, 4 July 2013 at 22:35:27 UTC, Jonathan M Davis wrote:
 On Friday, July 05, 2013 00:29:20 JS wrote:
 import std.stdio, std.cstream;
 
 
 template test(alias x)
 {
 	string func()
 	{
 		string s = "beta";
 		//pragma(msg, s);
 		return s;
 	}
 	enum test = func();
 }
 
 void main(string[] args)
 {
 	mixin test!("alpha");
 	din.getc();
 }
 
 When I try to display a compiler msg using pragma on a string
 variable the mixin fails. Commenting out the pragma allows the
 mixin to work.
 
 While there may be some internal reason this shouldn't work it
 seems quite unnatural and took me a while to figure out it was
 pragma causing the problem in my code.
I wouldn't ever expect that pragma to work. pramga is a compile-time construct and requires compile-time arguments, whereas s is normal, local variable and not usable at compile-time except when the function it's in is called as part of CTFE. It would work if s were an enum, because the value of an enum must be known at compile time, but that's not the case with a normal string variable. - Jonathan M Davis
This is simply wrong. If s could not be used at compile time then the mixin could not be used at compile time... yet it can be and is being used and works fine when the pragma is removed... and one can even pragma the template name after the function and it will work.
Jul 04 2013
next sibling parent "Dicebot" <public dicebot.lv> writes:
On Thursday, 4 July 2013 at 22:48:50 UTC, JS wrote:
 This is simply wrong. If s could not be used at compile time 
 then the mixin could not be used at compile time... yet it can 
 be and is being used and works fine when the pragma is 
 removed... and one can even pragma the template name after the 
 function and it will work.
You are mixing together compile-time values and CTFE. While result of CTFE function is treated as compile-time value, anything inside acts quite similar to normal code. And pragma's are limited to pure compile-time stuff, like enum values. There is a proposal to add ctfeWriteln construct to help in such situation - it can be recognized by CTFE interpreter and ignored during run-time. But I don't know if it will be accepted.
Jul 04 2013
prev sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, July 05, 2013 00:48:49 JS wrote:
 This is simply wrong. If s could not be used at compile time then
 the mixin could not be used at compile time... yet it can be and
 is being used and works fine when the pragma is removed... and
 one can even pragma the template name after the function and it
 will work.
You're misunderstanding the difference between CTFE and stuff that has to be known at compile time. A function called with CTFE must be callable like any other function at runtime. There's nothing special about it. It can be called at compile time, but there can't be anything about its implementation which requires it to be called at compile time. The only reason that the function is even being called at compile time is because it's being used to initialize an enum. Contrast this with the value of an enum, which _must_ be known at compile time. - Jonathan m Davis
Jul 04 2013
parent reply "JS" <js.mdnq gmail.com> writes:
On Thursday, 4 July 2013 at 23:06:39 UTC, Jonathan M Davis wrote:
 On Friday, July 05, 2013 00:48:49 JS wrote:
 This is simply wrong. If s could not be used at compile time 
 then
 the mixin could not be used at compile time... yet it can be 
 and
 is being used and works fine when the pragma is removed... and
 one can even pragma the template name after the function and it
 will work.
You're misunderstanding the difference between CTFE and stuff that has to be known at compile time. A function called with CTFE must be callable like any other function at runtime. There's nothing special about it. It can be called at compile time, but there can't be anything about its implementation which requires it to be called at compile time. The only reason that the function is even being called at compile time is because it's being used to initialize an enum. Contrast this with the value of an enum, which _must_ be known at compile time. - Jonathan m Davis
It shouldn't matter that string can behave as a runtime or compile time construct. The fact is, if it's used at compile time it has compile time behavior and pragma should have no issues with it. Just because a function *can be* used a run time doesn't mean that when it is used at compile time it has be limited. My guess is it has to do with the evaluation order. pragma and lower level compile time constructs get precedence and never get to see higher level constructs like strings(almost surely because these higher level constructs were created after the fact). But there is no apriori reason why a compile time string can't be used in compile time functions. (regardless if a compile time string can also be used as a runtime string... since it is not) After all, what's the semantical difference between enum s = "a" ~ "b" ~ "c"; enum s = "a"; s ~= "b"; s ~= "c"; string s = "a" ~ "b" ~ "c"; string s = "a"; s ~= "b"; s ~= "c"; Only the first works and is very limiting. If you want to keep enums then allow them to be modified at compile time... since a modification at compile time has nothing to do with immutability since it is still immutable at runtime. that is, enum s = "a"; s ~= "b"; at compile time is not a violation of the immutability of an enum. Basically, come up with a compile time string that has all the properties of a string and act like an immutable string at runtime. runtime strings can be converted to this new type of string when they are used at compile time... but then this just results in using the standard d string. I think it's a logical flaw in D's CTFE system rather than some innate reason why it doesn't work.
Jul 04 2013
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, July 05, 2013 01:51:56 JS wrote:
 I think it's a logical flaw in D's CTFE system rather than some
 innate reason why it doesn't work.
The whole point of CTFE is to be able to call the same function at compile time that you call at runtime. Having a function work at compile time but not runtime would fundamentally break CTFE. And it's _way_ easier to reason about what code is going to do if you understand the difference between stuff that's initialized at compile time (like an enum) and stuff which is run at compile time. Trying to mix the two would muddle things considerably. In any case, I would shocked if Don thought that CTFE should work the way you think that it should work, and if you can't convince him, then odds are, you're out of luck. I'm just trying to explain to you how the language works and why what you're trying to do doesn't work. - Jonathan m Davis
Jul 04 2013
parent reply "JS" <js.mdnq gmail.com> writes:
On Friday, 5 July 2013 at 00:06:30 UTC, Jonathan M Davis wrote:
 On Friday, July 05, 2013 01:51:56 JS wrote:
 I think it's a logical flaw in D's CTFE system rather than some
 innate reason why it doesn't work.
The whole point of CTFE is to be able to call the same function at compile time that you call at runtime. Having a function work at compile time but not runtime would fundamentally break CTFE. And it's _way_ easier to reason about what code is going to do if you understand the difference between stuff that's initialized at compile time (like an enum) and stuff which is run at compile time. Trying to mix the two would muddle things considerably. In any case, I would shocked if Don thought that CTFE should work the way you think that it should work, and if you can't convince him, then odds are, you're out of luck. I'm just trying to explain to you how the language works and why what you're trying to do doesn't work. - Jonathan m Davis
Well, duh. Just because something works the way it works doesn't mean it's the right or best way. Maybe a CTFE is suppose to have the exact same runtime and compile time behavior... it that is the case then we need something that is more powerful for compile time meta programming. At the moment all we have is basically CTFE. I don't see why it is important to try and force a square peg into a round hole just because you have a square peg. In any case, I seriously doubt that providing an "enum" with string concatenation at compile time would cause any difficulty and only make life much easier. If it breaks the CTFE common design between runtime and compile time then come up with a better way like having a compile time only meta functions that are meant to be used at compile time only for meta programming... it's not much of a leap from CTFE's... or allow CTFE's to be marked for compile time only which will allow enum string concatenation operations. Just because something "can't" be done doesn't mean it can't...
Jul 04 2013
parent reply "Dicebot" <public dicebot.lv> writes:
On Friday, 5 July 2013 at 00:44:24 UTC, JS wrote:
 Well, duh. Just because something works the way it works 
 doesn't mean it's the right or best way.
You are welcome to make a DIP and try to prove that your proposed alternative is better. Chance of success is low but it is possible. In the meanwhile I find the current system really well-designed and consistent.
Jul 05 2013
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, July 05, 2013 09:58:24 Dicebot wrote:
 In the meanwhile I find the current system really well-designed
 and consistent.
Agreed. - Jonathan M Davis
Jul 05 2013
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Jul 04, 2013 at 03:35:09PM -0700, Jonathan M Davis wrote:
 On Friday, July 05, 2013 00:29:20 JS wrote:
 import std.stdio, std.cstream;
 
 
 template test(alias x)
 {
 	string func()
 	{
 		string s = "beta";
 		//pragma(msg, s);
 		return s;
 	}
 	enum test = func();
 }
 
 void main(string[] args)
 {
 	mixin test!("alpha");
 	din.getc();
 }
 
 When I try to display a compiler msg using pragma on a string
 variable the mixin fails. Commenting out the pragma allows the
 mixin to work.
 
 While there may be some internal reason this shouldn't work it
 seems quite unnatural and took me a while to figure out it was
 pragma causing the problem in my code.
I wouldn't ever expect that pragma to work. pramga is a compile-time construct and requires compile-time arguments, whereas s is normal, local variable and not usable at compile-time except when the function it's in is called as part of CTFE. It would work if s were an enum, because the value of an enum must be known at compile time, but that's not the case with a normal string variable.
[...] Fair enough, but in this case, couldn't the compiler figure out that in this case s must always be known at compile-time? Since otherwise, it's not possible for enum test to work. Granted, this may not be something implementable, since it looks suspiciously similar to solving the halting problem. T -- It is impossible to make anything foolproof because fools are so ingenious. -- Sammy
Jul 04 2013