Text.Printf replacement?

Bart Massey bart at cs.pdx.edu
Fri Sep 6 19:51:08 CEST 2013

Current Text.Printf mainly fails to support the C printf modifiers '#'
and ' ', as well as the size modifier letters: fixing the former alone
would make it pass the bulk of the tests. There are also some
"differences of interpretation" with respect to the meaning of the
precision, alignment and fill specifiers: in many cases, I am in
sympathy with the Text.Printf interpretation, but I ultimately decided
to respect the C printf semantics; these are all extreme corner cases,
and I wouldn't expect any existing Haskell program to notice the
change. Finally, floating point formatting was somewhat different, and
still is, since the C spec here is fairly insane and also I didn't
want to break back-compatibility with existing code: in particular, C
printf likes to use a default precision of 6 total digits for things,
while Haskell treats the precision specifier as number of digits after
the decimal point and defaults to infinity.

I should note that none of these printf tests were written by me: they
were pulled from several test suites from other projects. It took
substantial editing to remove invalid tests to get C printf to pass.


On Fri, Sep 6, 2013 at 5:54 AM, Roman Cheplyaka <roma at ro-che.info> wrote:
> Hi Bart,
> Great job!
> Could you elaborate on what kind of test failures you see with the
> current Text.Printf, and which parts of printf(3) are not supported
> there?
> Roman
> * Bart Massey <bart at cs.pdx.edu> [2013-09-05 19:16:59-0700]
>> Greetings all! It's been many years since I have been subscribed to
>> this list, and now I come back with a big ask. :-) Here goes...
>> (tl;dr: I'd like to replace Text.Printf with a "better" version I've
>> written. I could use some help to get this to happen.)
>> If you go to http://github.com/BartMassey/extensible-printf you will
>> find Text.Printf.Extensible, my substantially-rewritten version of
>> Text.Printf.
>> * The primary goal, as the name suggests, was to allow the extension
>> of Haskell printf to user datatypes, a goal I achieved by modifying
>> the Text.Printf source using roughly the approach suggested by Meacham
>> and Marlow in an old email thread here. By the time I was done with
>> everything, I'd made changes to much of the source, but the structure
>> and a lot of the code is still recognizably there. I documented
>> everything a bit more in the process of figuring out how it all
>> worked.
>> * A second goal was to extend printf to support as much of the C
>> printf(3) format string syntax as seemed practicable: I did that, too.
>> See the documentation for details.
>> * A third goal was to produce something that was somewhat tested. See
>> http://github.com/BartMassey/printf-tests for a test suite of 300+
>> tests, gathered from printf test suites found on the Internet, that
>> Text.Printf.Extensible passes. (Text.Printf fails about half of them.)
>> * A fourth goal was to be 100% backward-compatible with the existing
>> Text.Printf. I haven't done sufficient testing to be sure, but on the
>> face of it existing programs should just work.
>> So here's the deal: I could just push this onto Hackage as
>> extensible-printf and call it a day. However, then we'd still have a
>> known-broken and not-extensible standard Text.Printf, and
>> extensible-printf would have to be maintained forever. Better, IMHO,
>> is to just replace the existing Text.Printf code with my rework.
>> One issue is that I would love to have someone who is not me shepherd
>> this work through the Library Submission process. I don't read this
>> email list so regularly, and so I'd be bad at facilitating an active
>> discussion.
>> Another issue is that a patch should be done to merge the tiny changes
>> in Text.Printf.Extensible.AltFloat back into Numeric. I'm happy to
>> prepare such a patch, but someone will have to show me how to build
>> base so that I can test my work. Is there any way to do it without
>> also building GHC? I tried, and became very confused.
>> A final issue has to do with the return type of Text.Printf.printf,
>> which is polymorphic between String and IO a. I'm sure this seemed
>> like a good idea at the time, but it's not so ideal today: GHC gives a
>> warning when printf is used at IO a unless you explicitly ignore the
>> result. (Worse still, if you mistakenly try to *use* the result,
>> you'll likely end up with a run-time error.) The obvious choices are
>> to somehow get printf to return String / IO () instead, something I
>> could not figure out the type magic to accomplish, or to provide some
>> alternate names for non-return-polymorphic functions. I'm leaning
>> toward putFmt, hPutFmt (synonymous with hprintf) and sFmt, but I'm
>> totally open to alternate suggestions. If we go forward, though, it
>> seems like this is something we should fix one way or the other. If
>> someone can figure out the type magic, we could fix it regardless.
>> Thanks much for reading! Regardless, the code was fun to write, and I
>> hope it will be useful to someone other than me.
>> Bart Massey
>> bart at cs.pdx.edu
>> _______________________________________________
>> Libraries mailing list
>> Libraries at haskell.org
>> http://www.haskell.org/mailman/listinfo/libraries

More information about the Libraries mailing list