-
-
Notifications
You must be signed in to change notification settings - Fork 700
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add print #3971
Add print #3971
Conversation
/** | ||
|
||
Writes its arguments in text format to the file separated pairwise by a | ||
space (or custom `separator`), followed by a newline (or custom `eol`). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Params:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Example(s):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The examples should be taken care of by the ddoc'd unittest(s).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I always forget that feature when looking at code.
Wow, this is not how I would have expected it to work. Is the mixin required? Seems like you could just call |
{ | ||
void printCSVRow(Data...)(Data data) | ||
{ | ||
print!", "(data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wouldn't actually be legal csv.... but it might be if the print function could also take a per-item transformation function to quote it properly. csv technically shouldn't have a space after the comma either.
The transformation function might just be interesting though, but it might also complicate it more than is worth doing. Some kinda of dg(item.asString) that defaults to identity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Echoing my statement above, the unit test should not print to stdout. The unit tests should either
- Replace stdout with a temp file (temporarily)
- Use a temp file directly.
You could also have a unit test that just verified the call could compile. Wouldn't make a good example though.
Heh, I swear I didn't look at this first: https://forum.dlang.org/post/mailman.4272.1454600460.22025.digitalmars-d-learn@puremagic.com |
This is a tangential thought but something that might be interesting is to consider how structs are written. writeln by default does something like Is the goal of Maybe that's outside the scope of this function though. |
@adamdruppe IMO this is a function for the user that does not want to type: int a, b;
writeln(a, ' ', b); but rather have it the python way a = 0
b = 0
print(a,b); nothing more nothing less |
@burner correct. @schveiguy the mixin is for efficiency. |
hmm, all right. One request though: make it call |
IMO the name print will lead to people mistaking this function as the D idomatic way of writing data to files, instead of write or output ranges. Therefore, I would like the function to be renamed to something like dump. Something that makes it somewhat clear that this is a convenient function to "dump" out data. |
Meh. this is for debugging right? I only bring up the point because the function you have there is really hard to debug, understand, read, explain. Artur's version is much easier. |
To put @schveiguy's point in a different way, because this is for debugging, you would want compile times to be as fast as possible. |
I'm not sure about this. If we are talking about adding a debugging aid, what about something similar to Julia's |
@klickverbot I like that idea. One of the reasons I find myself not needing something like Having something like |
@schveiguy: Yes, that's precisely the idea. I was surprised how useful the feature actually was in debugging Julia code. Edit: Sorry, hit the wrong button. |
On Thu, Feb 04, 2016 at 10:03:11AM -0800, Steven Schveighoffer wrote:
If they are taken as alias arguments, you don't even need to quote them. I've done this with function calls and such, and structs formatted with indentation to make it far more readable. Pretty nice. |
Throws: $(D Exception) if the file is not opened. | ||
$(D ErrnoException) on an error writing to the file. | ||
*/ | ||
void print(string separator = " ", string eol = "\n", S...)(S args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like putting this inside File
. It's yet another method that does something another method already does, except different. What about move this to module scope and take File
as first argument, so that we can make use of UFCS?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, formatting a list of items delimited by some string isn't specific to file I/O; what about something in std.format
that does this generically, returning an input range of char
(or whatever) so that it can be reused for other stuff that doesn't involve file I/O?
That wouldn't work for complex expressions, though, or have things changed on that front lately? |
On Thu, Feb 04, 2016 at 10:28:15AM -0800, David Nadlinger wrote:
I don't think strings would either though because they wouldn't be mixed into the same scope... |
… and of course you are right. Have been using too many languages recently, I guess… |
I agree. I think the Ruby debugger Pry outputs a pretty good structure. This is an example:
|
|
On Thu, Feb 04, 2016 at 06:26:10PM -0800, Joseph Emmons wrote:
hmm, that's clever! |
When Would be nice if we could do something like |
Wait, why would this make a difference? The loop will be unrolled during compilation so the ternary will be folded away, no? |
Hey guys, I'm all for adding a @adamdruppe I'm considering adding |
@CyberShadow I meant mixin as opposed to multiple calls to |
On Sun, Feb 07, 2016 at 10:07:22AM -0800, David Nadlinger wrote:
Yeah, but even then, you could do a .join(", ") or whatever...
I agree. Even if it isn't great in the first pass, if we say "this is for a debug dump, meant to be pretty whatever that may be" then it keeps the door open to change it later. |
No, you can't if the items have different types etc. @adamdruppe I think your counterpoint overall doesn't stand. There are ways to do what print does. Neither is easy and brief. Overall: sigh. Yet Another Great Debate. Regarding this question by @klickverbot:
Let's not get all self-important. This is not a "design choice" as much as - do we want to provide this convenience function or not. There's no reasoning or algorithm that takes us to the decision. I disagree that the addition would be confusing. It's just a different function that does a different thing. Regarding its usefulness, I have plenty in the code I'm writing. The way I look at it, it's almost always an error to print two integers next to each other. yet writeln is liable to do exactly that. Why, then, not offer a function that doesn't do the wrong thing out of the box. Etc. I'm in favor of adding it, but honest the more churn in this discussion the more my enthusiasm drops. About |
Yep, let's merge and move on. The goal here is to save some keystrokes for a very common case, and some edit-build-run cycles in those long debugging nights when you forget to add the 👍 |
What would you expect? Would you prefer me just saying: No, let's not do it? Adding what amounts to a slightly modified copy of something else to the standard library is a questionable proposition to begin with. There can be reasons to do so, but the reasons for it'd better be clear (cf. the
If you see
What about two strings though? Etc., etc.
I'm glad I can be of help to avoid rash decisions. If it was a great addition your enthusiasm, at least for the thing itself, would stay. There might be not a huge design space to explore here, but it's definitely more than the simple yes/no choice you make it out to be. Do we offer separate print/println versions (I'd say: no), do we declare it as a debugging helper and remove the formatting arguments (I'd say: yes), etc. |
On Sun, Feb 07, 2016 at 03:23:16PM -0800, Andrei Alexandrescu wrote:
I think we're more on the same side than not.. I think the writeln!", " option fails on the easy or brief metric (compared to the competition).
I actually wrote briefly about this thread in TWID today because I think it reflects a Phobos philosophy. This individual function isn't a big deal, but I do think it indicates a bigger picture that we ought to have a conversation about. I'm sure many of the other commentators feel the same way.
I'd find a debug dump function to be enormously useful too.
What's the difference between substr and substring in Javascript? I fear write vs print in D could be a similar FAQ down the line... especially since writef is evolved from printf. So are we going to be in a situation where "don't use printf, writef is better oh but wait don't use writef, print is better, well, except for those cases where you don't want the space." |
Personally, I was very surprised when I found out that
Of course. You're proposing a function that's purely a convenience function. What else was going to happen? Personally, it's not something that I've ever felt a need for. I'd just use So, I don't personally see any real value in this, I will never use it, and if it were purely up to me, I wouldn't add it, but if you want it, I don't care enough to fight against it. Having a single way to do things vs having some convenience functions for certain use cases is always highly subjective and ripe for debate. The primary cost to this in the long run is going to be that there's yet one more printing function added to the list for D programmers to learn and distinguish, which isn't exactly a good thing. But maybe the convenience it provides is worth it for those folks who would use it. Ultimately, it's a judgement call. |
As a follow-up on this, even though the source code turned out quite a bit nicer, I wasn't able to make this work. Maybe with future compiler improvements it will be possible, or maybe I was missing something. If a string mixin is the only way to accomplish this and the performance benefit is worth it, then LGTM. |
Implementation is now a lot simpler, owing to the forum discussion. |
The way I see it is their charters are different, one is not better or worse than the other. Why would one advise to prefer |
Implementation looks much better! |
Some comments:
Especially because in Python it's the default output method and stuff like Ideas to resolve this
Yep as far as I understood it that seems to be general consensus here. Is there anyone really opposing this idea? @tofuninja I would love to see more discussions on |
Can this move forward now into Phobos? |
@ixid A couple of reviewers and myself don't really like the confusion generated by introducing |
Could you present anything to back up this supposed confusion? It's an extremely weak argument without any apparent evidence or examples from other communities. There are already many different functions that write or print, it's not as if this is a pristine area that will be muddied. There are also many languages that use print to print and no one I've seen appears to be particularly confused by that. |
It's not as many of the previous speakers have explained (see e.g. @klickverbot's post the problem is not that Besides the main use case of this function is to dump some data during development, which should be done via a (to-be-added) |
Newbies could use print out of the gate without needing to read the docs, that's the point. They certainly would need to read them to use write, writef writefl, writeln and understand what percent symbols they are supposed to be using and how to get a new line at the end as well as what on earth the current four write versions are supposed to do (fln is not a great mnemonic). I would hope tutorials would fairly quickly move towards 'use print unless you want to do something more complex with formatting in which case read these docs for those functions'. This is lowering the barrier for newbies, not increasing it. Print is much easier to remember than echo or dump as those are not as closely associated with generating output in most people's minds. The use case for this function is similar to that for writeln but easier to use. This quibbling about names seems more obstructive than productive or insightful. The cognitive load is tiny to non-existent. Just to add- some of the suggested alternative names are fine like 'say' if that is the sticking point. |
|
||
Throws: $(D Exception) if the file is not opened. | ||
$(D ErrnoException) on an error writing to the file. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
writeln
and print
should refer to each other via See_Also
, to reduce confusion.
Could someone add the @andralex label? Thanks! |
OK, batlight's on :) |
What other languages use |
What about a compromise between @tofuninja's
Output:
http://dpaste.dzfl.pl/4b2a10546c0b ? |
@ZombineDev - I really like this! How about submitting a new PR? Probably the name 'dump' is still better fit your function though.. |
{ | ||
import std.range : repeat; | ||
import std.string : join; | ||
static immutable fmt = repeat("%s", S.length).join(separator) ~ eol; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is over engineering. A static foreach loop for args
and default FormatSpec!char
along with formatValue
would be faster to compile and faster to execute, and looks clear.
I'll close this as too controversial. |
Suggested by a user frustrated by the OOB experience, which echoes a long-time annoyance of mine while debugging using writeln. Here be Another Epic Debate.