www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - CTFE writeln again (__ctfeWriteln)

reply KennyTM~ <kennytm gmail.com> writes:
Pull request: https://github.com/D-Programming-Language/dmd/pull/296

Previous discussion: 
http://www.digitalmars.com/d/archives/digitalmars/D/CTFE_writeln_140241.html

This is the 2nd try to add a compile-time printing facility to D. The 
previous pull request uses std.stdio.writeln which causes some concern, 
and then left unattended for a few weeks after the last comment. So I go 
for my 2nd alternative, which is to add a magic function __ctfeWriteln 
that does the same.

In my implementation, __ctfeWriteln will print the interpreted arguments 
to stdmsg when CTFE-ed, and is a no-op in runtime (it can be configured 
to throw an exception or actually print the arguments or anything you like).
Aug 07 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
KennyTM~:

 So I go for my 2nd alternative, which is to add a magic function __ctfeWriteln 
 that does the same.
 
 In my implementation, __ctfeWriteln will print the interpreted arguments 
 to stdmsg when CTFE-ed, and is a no-op in runtime (it can be configured 
 to throw an exception or actually print the arguments or anything you like).
Important: if there is a single function then I do *not* want it to print a newline. Adding a newline when you need it is much simpler than removing it if you do not want it. If you really want a newline too, then create two functions, (similar to write and writeln), but the most important is the one without newline. What's the purpose of the two leading underscores? I prefer it without them. This is supposed to be a clean and nice function, not an unsafe ugly thing :-) So I think a "ctfeWrite" name is better. Generally I'd like this functions to print equally at compile-time and run-time, but I see there are some problems in doing this... If the function"ctfeWrite" becomes too much complex (to print arbitrary things), then for me it's acceptable it to print just strings too (with no newline added). Bye and thank you for your work, bearophile
Aug 07 2011
parent reply KennyTM~ <kennytm gmail.com> writes:
On Aug 8, 11 05:56, bearophile wrote:
 KennyTM~:

 So I go for my 2nd alternative, which is to add a magic function __ctfeWriteln
 that does the same.

 In my implementation, __ctfeWriteln will print the interpreted arguments
 to stdmsg when CTFE-ed, and is a no-op in runtime (it can be configured
 to throw an exception or actually print the arguments or anything you like).
Important: if there is a single function then I do *not* want it to print a newline. Adding a newline when you need it is much simpler than removing it if you do not want it. If you really want a newline too, then create two functions, (similar to write and writeln), but the most important is the one without newline. What's the purpose of the two leading underscores? I prefer it without them. This is supposed to be a clean and nice function, not an unsafe ugly thing :-) So I think a "ctfeWrite" name is better.
Two leading underscores means it's a reserved identifier which should have no chance of collision. It does not mean unsafe. Also, it's named after the existing identifier '__ctfe'.
 Generally I'd like this functions to print equally at compile-time and
run-time, but I see there are some problems in doing this...

 If the function"ctfeWrite" becomes too much complex (to print arbitrary
things), then for me it's acceptable it to print just strings too (with no
newline added).
__ctfeWrite is not complex, but I don't see the need for it.
 Bye and thank you for your work,
 bearophile
Aug 07 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
KennyTM~:

 __ctfeWrite is not complex, but I don't see the need for it.
I don't understand your point. Given __ctfeWrite you are able to create a __ctfeWriteln but you can't do the opposite. If I have to print something complex, like something tree-shaped, and I have just __ctfeWriteln, to create the printing I need to first put everything into a huge string, and print it. If I have __ctfeWrite I am able to write it one bit at a time. Not having a compulsive newline was the strongest requirement in my original enhancement request: http://d.puremagic.com/issues/show_bug.cgi?id=3952 The obligatory newline of pragma(msg) has given me several problems, it's much less useful because of this. Bye, bearophile
Aug 07 2011
parent reply KennyTM~ <kennytm gmail.com> writes:
On Aug 8, 11 06:45, bearophile wrote:
 KennyTM~:

 __ctfeWrite is not complex, but I don't see the need for it.
I don't understand your point. Given __ctfeWrite you are able to create a __ctfeWriteln but you can't do the opposite. If I have to print something complex, like something tree-shaped, and I have just __ctfeWriteln, to create the printing I need to first put everything into a huge string, and print it. If I have __ctfeWrite I am able to write it one bit at a time. Not having a compulsive newline was the strongest requirement in my original enhancement request: http://d.puremagic.com/issues/show_bug.cgi?id=3952 The obligatory newline of pragma(msg) has given me several problems, it's much less useful because of this. Bye, bearophile
I understand that you could implement `writeln` in terms of `write`, but I question its practical value. Why do you need to print a tree at compile time? pragma(msg) and __ctfeWriteln are mainly for debugging, and adding a newline is very suitable (e.g. it won't mess up the error message in the next line).
Aug 08 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
KennyTM~:

 I understand that you could implement `writeln` in terms of `write`, but 
 I question its practical value.   Why do you need to print a tree at 
 compile time?  pragma(msg) and __ctfeWriteln are mainly for debugging, 
 and adding a newline is very suitable (e.g. it won't mess up the error 
 message in the next line).
What if you are debugging a program (as I have written) that uses trees? I'd like the freedom to print textual trees one piece at a time (in Python I have written two or three small programs that print trees textually). It's not just trees, it's also other 2D tables. If you add the newline then I am forced to print one table line at a time, I can't print its items one after the other. Even if printing at compile-time is mainly for debugging, if you add that newline you make other unexpected future usages harder. You do not know how D will be used ten years from now. In Python2 there the main printing statement adds a space between printed items. This is quite handy. But what if you do not want that space? Things gets harder. They have had to wait for Python3 to fix this design mistake. The moral of the Python2 story is that you are allowed to add a handy printing function (that adds newlines and spaces) only if you _also_ have a function that prints nude strings (or nude chars). But if you have only one function, then it has to be a function that doesn't add extra things that you can't remove. (An alternative design, if you want a single function is a function templated on a boolean __ctfeWrite!(bool newline=true)(...). I don't know how much nice this is). Bye, bearophile
Aug 08 2011
parent reply KennyTM~ <kennytm gmail.com> writes:
On Aug 9, 11 03:19, bearophile wrote:
 KennyTM~:

 I understand that you could implement `writeln` in terms of `write`, but
 I question its practical value.   Why do you need to print a tree at
 compile time?  pragma(msg) and __ctfeWriteln are mainly for debugging,
 and adding a newline is very suitable (e.g. it won't mess up the error
 message in the next line).
What if you are debugging a program (as I have written) that uses trees? I'd like the freedom to print textual trees one piece at a time (in Python I have written two or three small programs that print trees textually). It's not just trees, it's also other 2D tables. If you add the newline then I am forced to print one table line at a time, I can't print its items one after the other. Even if printing at compile-time is mainly for debugging, if you add that newline you make other unexpected future usages harder. You do not know how D will be used ten years from now. In Python2 there the main printing statement adds a space between printed items. This is quite handy. But what if you do not want that space? Things gets harder. They have had to wait for Python3 to fix this design mistake. The moral of the Python2 story is that you are allowed to add a handy printing function (that adds newlines and spaces) only if you _also_ have a function that prints nude strings (or nude chars). But if you have only one function, then it has to be a function that doesn't add extra things that you can't remove. (An alternative design, if you want a single function is a function templated on a boolean __ctfeWrite!(bool newline=true)(...). I don't know how much nice this is). Bye, bearophile
A __ctfeWrite could certainly be added 10 year from now if that's required, but at the current stage, I still see no compelling reason for that. If you have a tree, probably you'd write a toString() anyway, and for a 2D table, you could write a whole row at a time as an array. foreach (row; twoDarray) { __ctfeWriteln(row); ... } Meanwhile, using __ctfeWrite improperly could easily mess up with error messages which breaks IDE on locating the line of error. 1, 2, 3, x.d(55): Error: dereference of null pointer 'null' x.d(47): Error: cannot evaluate delegate pure nothrow system int() Python's print statement/function is irrelevant. We're not talking about printing at runtime where having the possibility to format things pretty is essential. Printing things at compile time should always be for debugging or error reporting which should be kept simple. Unless there are more _people_ supporting this, or the authority (those who can commit into DMD directly) require having a __ctfeWrite, I'll refrain from adding this generalization to D2.
Aug 08 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Double leading underscores are for temporary things, that will change and
improve, like __traits. But this ctWriteln is meant to stay. And the leading
"ctfe" is redundant, so I suggest to call it ctWriteln, there is no need to
give it an ugly name. It means "compile time write with newline" instead of a
"ugly temporary compile time function evaluation write with newline".

Bye,
bearophile
Aug 08 2011
next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
 Double leading underscores are for temporary things, that will change and
 improve, like __traits. But this ctWriteln is meant to stay. And the
 leading "ctfe" is redundant, so I suggest to call it ctWriteln, there is
 no need to give it an ugly name. It means "compile time write with
 newline" instead of a "ugly temporary compile time function evaluation
 write with newline".
I don't know where you got that idea. Starting symbol names with __ is reserved for the compiler (and maybe the runtime). There's nothing about it which says anything about it being temporary or that it will ever change. It doesn't mean that it isn't temporary or that it isn't going to change either. It's just a naming scheme which is reserved by the compiler to do with as the compiler developers see fit. - Jonathan M Davis
Aug 08 2011
prev sibling parent Don <nospam nospam.com> writes:
bearophile wrote:
 Double leading underscores are for temporary things, that will change and
improve, like __traits. 
 But this ctWriteln is meant to stay.
No it isn't. If we get bug 3702 ("magic namespace") approved, the name of __ctfe and __ctfeWriteln will change. They are intentionally ugly.
Aug 08 2011
prev sibling parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 08.08.2011 1:38, KennyTM~ wrote:
 Pull request: https://github.com/D-Programming-Language/dmd/pull/296

 Previous discussion: 
 http://www.digitalmars.com/d/archives/digitalmars/D/CTFE_writeln_140241.html

 This is the 2nd try to add a compile-time printing facility to D. The 
 previous pull request uses std.stdio.writeln which causes some 
 concern, and then left unattended for a few weeks after the last 
 comment. So I go for my 2nd alternative, which is to add a magic 
 function __ctfeWriteln that does the same.

 In my implementation, __ctfeWriteln will print the interpreted 
 arguments to stdmsg when CTFE-ed, and is a no-op in runtime (it can be 
 configured to throw an exception or actually print the arguments or 
 anything you like).
It's indeed a valuable built in, hopefully it'll get pulled, debugging C-T vs R-T inconsistencies is quite a painful exercise ATM. -- Dmitry Olshansky
Aug 07 2011