<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Wed, Oct 12, 2016 at 11:38 AM James Y Knight <<a href="mailto:jyknight@google.com">jyknight@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg">On Wed, Oct 12, 2016 at 1:28 PM, Zachary Turner <span dir="ltr" class="gmail_msg"><<a href="mailto:zturner@google.com" class="gmail_msg" target="_blank">zturner@google.com</a>></span> wrote:<br class="gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr" class="gmail_msg"><br class="gmail_msg"><div class="gmail_quote gmail_msg"><span class="m_-4948597816383306175m_-8573396319951359218gmail- gmail_msg"><div dir="ltr" class="gmail_msg">On Wed, Oct 12, 2016 at 10:13 AM James Y Knight <<a href="mailto:jyknight@google.com" class="gmail_msg" target="_blank">jyknight@google.com</a>> wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr" class="m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"><div class="m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"><br class="gmail_msg"></div></div><div dir="ltr" class="m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"><div class="gmail_extra m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"><div class="gmail_quote m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"><div class="m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"><br class="m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"></div></div></div></div><div dir="ltr" class="m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"><div class="gmail_extra m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"><div class="gmail_quote m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"><div class="m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg">I wonder what use cases you envision for this? Why does LLVM need a super extensible flexible formatting library? I mean -- if you were developing this as a standalone project, that seems like maybe a nice feature. But I see no rationale as to why LLVM should include it.</div></div></div></div></blockquote></span><div class="gmail_msg">We were discussing this on IRC chat the other night, but I believe many people underestimate the need for string formatting.  Here are some data points:<div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">1. There are currently 1,637 calls to llvm::format() across the codebase, and this doesn't include calls to format_hex(), format_decimal(), and the other variants.</div><div class="gmail_msg">2. LLVM consists of a large number (20+ at a minimum) of focused tools (llc, lli, llvm-dwarfdump, llvm-objdump, etc) whose sole purpose is to output formatted text.  Consider the use case of printing a verbose disassembly listing which is fed into FileCheck.</div><div class="gmail_msg">3. Even the "flagship" tools such as clang have need for string formatting when writing diagnostic messages.</div><div class="gmail_msg">4. LLDB in particular has this kind of thing *everywhere*.  I'm talking about anywhere from 3-50+ times <b class="gmail_msg">per function</b> (and that's not an exaggeration) for logging purposes.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">That said, LLVM already includes a formatting library.  llvm::format().  So what would be the rationale *against* a better, safer, and easier version of the same thing?</div></div></div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg">The arguments against for me are roughly:</div><div class="gmail_msg">1. It introduces a new formatting language that people need to learn.</div></div></div></div></blockquote><div>We learn new things every day.  Among the new things that people would need to learn, I would rank this among the least difficult we can think of.  The syntax is familiar to anyone who has ever used Python or C# (which is probably most people here).</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg">2. People will still continue using printf-style formattings strings, too, because everyone **always** does, whenever anyone's ever introduced another formatting language anywhere.</div></div></div></div></blockquote><div>Not if the end-state is that we remove llvm::format()</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg">3. The extensible formatting support is a) not obviously necessary, and b) will be more difficult to understand for readers, versus calling a function with normal function arguments.</div></div></div></div></blockquote><div>I disagree.  I would be surprised if anyone thinks</div><div><br></div><div>os.format("Start: {0}, End: {1}, Duration: {2:ms} milliseconds", start, end, end-start); </div><div><br></div><div>is harder to understand than pretty much anything else you could possibly write.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg"> <br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr" class="gmail_msg"><div class="gmail_quote gmail_msg"><span class="m_-4948597816383306175m_-8573396319951359218gmail- gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr" class="m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"><div class="gmail_extra m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"><div class="gmail_quote m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"><div class="m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"><br class="m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"></div><div class="m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg">That is to say: wouldn't a much-simpler printf replacement, implemented with variadic templates instead of C varargs (and which therefore doesn't require size/signedness prefixes on %d) be sufficient for LLVM?</div></div></div></div></blockquote><blockquote class="gmail_quote gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr" class="m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"><div class="gmail_extra m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"><div class="gmail_quote m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"><div class="m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"><br class="m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"></div><div class="m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg">You can do that as a drop-in improvement for llvm::format, replacing the call to snprintf inside the implementation with a new implementation that actually uses the type information.<br class="m_-4948597816383306175m_-8573396319951359218gmail-m_4680252615225930183gmail_msg gmail_msg"></div></div></div></div></blockquote></span><div class="gmail_msg">How would you format user-defined types using this?  I gave an example earlier:  Consider you have a start time and an end time in std::chrono types, and you want to print the start, end, and duration.  The code to do this using llvm::format() or stream operators is horrible.</div></div></div>
</blockquote></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"></div><br class="m_-4948597816383306175m_-8573396319951359218gmail-Apple-interchange-newline gmail_msg">I'd call a function that returns a string, and print the string.<br class="gmail_msg"></div><div class="gmail_extra gmail_msg">E.g.:</div><div class="gmail_extra gmail_msg">format("Started at %s, ended at %s", </div><div class="gmail_extra gmail_msg">  format_date("%d/%m/%Y %T", start_time),</div><div class="gmail_extra gmail_msg">  format_date("%d/%m/%Y %T", end_time)<span style="font-size:12.8px" class="gmail_msg">);</span></div></div></blockquote><div>We take care to make our stream based formatting as efficient as possible since it is used so pervasively throughout LLVM.  There are quite a few unnecessary copies in here, and more room for programmer error in doing the formatting.</div></div></div>