
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@cs.pdx.edu

I prefer a well-typed extensible combinator approach like:
http://chrisdone.com/holey-format/Text-Format.html
than the stringly typed approach of printf.
On 6 September 2013 04:16, Bart Massey
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@cs.pdx.edu
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

I'd prefer strongly typed formatting too, although I'm not sure I'm
smart enough to learn the cool-looking package you point to :-).
However, we are unlikely to remove Text.Printf as a formatting option
for those who prefer "stringly typed" (nice pun!). An option I'd
thought about is to actually process the format string using Template
Haskell :-). It would make the calling convention a little
syntactically-different, I guess, but would let me use my comfortable
old printf format strings and still get static typechecking.
In any case, in my motivating application
(http://github.com/BartMassey/hseq -- yes, it's the Haskell sequence)
I am forced by the existing spec to expose printf format strings to
the user. Bleah, but there I am.
--Bart
On Fri, Sep 6, 2013 at 4:48 AM, Christopher Done
I prefer a well-typed extensible combinator approach like:
http://chrisdone.com/holey-format/Text-Format.html
than the stringly typed approach of printf.
On 6 September 2013 04:16, Bart Massey
wrote: 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@cs.pdx.edu
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

FWIW printf-mauke has a TH quoter:
http://hackage.haskell.org/packages/archive/printf-mauke/0.5.1/doc/html/Text...
On 6 September 2013 20:05, Bart Massey
I'd prefer strongly typed formatting too, although I'm not sure I'm smart enough to learn the cool-looking package you point to :-). However, we are unlikely to remove Text.Printf as a formatting option for those who prefer "stringly typed" (nice pun!). An option I'd thought about is to actually process the format string using Template Haskell :-). It would make the calling convention a little syntactically-different, I guess, but would let me use my comfortable old printf format strings and still get static typechecking.
In any case, in my motivating application (http://github.com/BartMassey/hseq -- yes, it's the Haskell sequence) I am forced by the existing spec to expose printf format strings to the user. Bleah, but there I am.
--Bart
On Fri, Sep 6, 2013 at 4:48 AM, Christopher Done
wrote: I prefer a well-typed extensible combinator approach like:
http://chrisdone.com/holey-format/Text-Format.html
than the stringly typed approach of printf.
On 6 September 2013 04:16, Bart Massey
wrote: 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@cs.pdx.edu
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Doh. How did I miss printf-mauke when I was digging through Hackage?
Looks like I've duplicated some work.
I think with the extensible-printf approach, bonus PrintfArg instances
should exist in the respective packages (bytestring, ffi, etc) rather
than being centralized in Text.Printf. If we end up using
extensible-printf, someone should put those patches in place.
--Bart
On Fri, Sep 6, 2013 at 11:10 AM, Christopher Done
FWIW printf-mauke has a TH quoter: http://hackage.haskell.org/packages/archive/printf-mauke/0.5.1/doc/html/Text...
On 6 September 2013 20:05, Bart Massey
wrote: I'd prefer strongly typed formatting too, although I'm not sure I'm smart enough to learn the cool-looking package you point to :-). However, we are unlikely to remove Text.Printf as a formatting option for those who prefer "stringly typed" (nice pun!). An option I'd thought about is to actually process the format string using Template Haskell :-). It would make the calling convention a little syntactically-different, I guess, but would let me use my comfortable old printf format strings and still get static typechecking.
In any case, in my motivating application (http://github.com/BartMassey/hseq -- yes, it's the Haskell sequence) I am forced by the existing spec to expose printf format strings to the user. Bleah, but there I am.
--Bart
On Fri, Sep 6, 2013 at 4:48 AM, Christopher Done
wrote: I prefer a well-typed extensible combinator approach like:
http://chrisdone.com/holey-format/Text-Format.html
than the stringly typed approach of printf.
On 6 September 2013 04:16, Bart Massey
wrote: 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@cs.pdx.edu
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

On Fri, Sep 6, 2013 at 4:48 AM, Christopher Done
I prefer a well-typed extensible combinator approach like:
http://chrisdone.com/holey-format/Text-Format.html
than the stringly typed approach of printf.
That's hardly relevant, as it sounds like Bart's work marks a considerable improvement to the existing printf code. Surely we should evaluate it on that basis, and not because it's not something entirely different. Lennart, are you on the libraries@ list? If Bart's work passes review and seems backwards compatible, do you have any objection to moving from your printf implementation to his?

On 9/6/13 3:55 PM, Bryan O'Sullivan wrote:
That's hardly relevant, as it sounds like Bart's work marks a considerable improvement to the existing printf code. Surely we should evaluate it on that basis, and not because it's not something entirely different.
Lennart, are you on the libraries@ list? If Bart's work passes review and seems backwards compatible, do you have any objection to moving from your printf implementation to his?
(cc Lennart directly, just in case) As far as I know, the current Printf has gone unpatched for years and effectively unmaintained. I'd like to propose A) that we seriously consider Bart's rewrite/replacement, and B) that in so doing we also seriously consider moving it _out_ of base and _into_ the platform, as part of our general slimming-down base process. Thoughts? --Gershom

It doesn't seem to me that Text.Printf belongs in base. Indeed, I
avoided using Data.Set in the implementation (and I think Lennart did
as well, as there's an obvious place for it) partly to avoid the whole
base/containers disaster. --Bart
On Fri, Sep 6, 2013 at 3:34 PM, Gershom Bazerman
On 9/6/13 3:55 PM, Bryan O'Sullivan wrote:
That's hardly relevant, as it sounds like Bart's work marks a considerable improvement to the existing printf code. Surely we should evaluate it on that basis, and not because it's not something entirely different.
Lennart, are you on the libraries@ list? If Bart's work passes review and seems backwards compatible, do you have any objection to moving from your printf implementation to his?
(cc Lennart directly, just in case)
As far as I know, the current Printf has gone unpatched for years and effectively unmaintained. I'd like to propose A) that we seriously consider Bart's rewrite/replacement, and B) that in so doing we also seriously consider moving it _out_ of base and _into_ the platform, as part of our general slimming-down base process.
Thoughts?
--Gershom
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Agreed. I see no reason for it to be in base.
Roman
* Bart Massey
It doesn't seem to me that Text.Printf belongs in base. Indeed, I avoided using Data.Set in the implementation (and I think Lennart did as well, as there's an obvious place for it) partly to avoid the whole base/containers disaster. --Bart
On Fri, Sep 6, 2013 at 3:34 PM, Gershom Bazerman
wrote: On 9/6/13 3:55 PM, Bryan O'Sullivan wrote:
That's hardly relevant, as it sounds like Bart's work marks a considerable improvement to the existing printf code. Surely we should evaluate it on that basis, and not because it's not something entirely different.
Lennart, are you on the libraries@ list? If Bart's work passes review and seems backwards compatible, do you have any objection to moving from your printf implementation to his?
(cc Lennart directly, just in case)
As far as I know, the current Printf has gone unpatched for years and effectively unmaintained. I'd like to propose A) that we seriously consider Bart's rewrite/replacement, and B) that in so doing we also seriously consider moving it _out_ of base and _into_ the platform, as part of our general slimming-down base process.
Thoughts?
--Gershom
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

I too would favor pushing it out to the platform.
On Fri, Sep 6, 2013 at 9:01 PM, Bart Massey
It doesn't seem to me that Text.Printf belongs in base. Indeed, I avoided using Data.Set in the implementation (and I think Lennart did as well, as there's an obvious place for it) partly to avoid the whole base/containers disaster. --Bart
On Fri, Sep 6, 2013 at 3:34 PM, Gershom Bazerman
wrote: On 9/6/13 3:55 PM, Bryan O'Sullivan wrote:
That's hardly relevant, as it sounds like Bart's work marks a
considerable
improvement to the existing printf code. Surely we should evaluate it on that basis, and not because it's not something entirely different.
Lennart, are you on the libraries@ list? If Bart's work passes review and seems backwards compatible, do you have any objection to moving from your printf implementation to his?
(cc Lennart directly, just in case)
As far as I know, the current Printf has gone unpatched for years and effectively unmaintained. I'd like to propose A) that we seriously consider Bart's rewrite/replacement, and B) that in so doing we also seriously consider moving it _out_ of base and _into_ the platform, as part of our general slimming-down base process.
Thoughts?
--Gershom
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Hi, Am Montag, den 09.09.2013, 10:32 -0700 schrieb Bryan O'Sullivan:
Is this something we'd like to fix in the run-up to 7.8? Otherwise I bet a small coin in the currency of your choice that it will get forgotten :-)
if there is consensus (and it seems there is), and someone creates a printf library in time so that users have to change nothing but their package imports to get their Printf-using code running again, then I’d say: Let’s do this now. Greetings, Joachim -- Joachim “nomeata” Breitner mail@joachim-breitner.de • http://www.joachim-breitner.de/ Jabber: nomeata@joachim-breitner.de • GPG-Key: 0x4743206C Debian Developer: nomeata@debian.org

Can't we consider them separately? A new printf library is nice, and
so is moving printf out of base, but I don't see why one should hold
up the other.
On Tue, Sep 10, 2013 at 2:09 PM, Joachim Breitner
Hi,
Am Montag, den 09.09.2013, 10:32 -0700 schrieb Bryan O'Sullivan:
Is this something we'd like to fix in the run-up to 7.8? Otherwise I bet a small coin in the currency of your choice that it will get forgotten :-)
if there is consensus (and it seems there is), and someone creates a printf library in time so that users have to change nothing but their package imports to get their Printf-using code running again, then I’d say: Let’s do this now.
Greetings, Joachim
-- Joachim “nomeata” Breitner mail@joachim-breitner.de • http://www.joachim-breitner.de/ Jabber: nomeata@joachim-breitner.de • GPG-Key: 0x4743206C Debian Developer: nomeata@debian.org
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Hi, Am Dienstag, den 10.09.2013, 14:14 -0700 schrieb Evan Laforge:
Can't we consider them separately? A new printf library is nice, and so is moving printf out of base, but I don't see why one should hold up the other.
well, where to do you want to move it to, if not into a printf library. (I did not say that it has to be the new code; that indeed could be handled separately.) Greetings, Joachim -- Joachim “nomeata” Breitner mail@joachim-breitner.de • http://www.joachim-breitner.de/ Jabber: nomeata@joachim-breitner.de • GPG-Key: 0x4743206C Debian Developer: nomeata@debian.org

On Tue, Sep 10, 2013 at 2:16 PM, Joachim Breitner
Hi,
Am Dienstag, den 10.09.2013, 14:14 -0700 schrieb Evan Laforge:
Can't we consider them separately? A new printf library is nice, and so is moving printf out of base, but I don't see why one should hold up the other.
well, where to do you want to move it to, if not into a printf library. (I did not say that it has to be the new code; that indeed could be handled separately.)
Ah yes, sorry I misunderstood then :) I only see two uses of printf in ghc: ghc/InteractiveUI.hs: let nums = map (printf "-%-3d:") [(1::Int)..] compiler/utils/Outputable.lhs: ppr (Fingerprint w1 w2) = text (printf "%016x%016x" w1 w2) So it seems easy to replace that with some hand-written formatting. If Bart's new printf is at least as good as the old one, then the printf package could start with that as 1.0, otherwise just copy the existing one, and Bart's new one would eventually become 2.0. I guess everyone's package breaks until they add a new printf dep. The new hackage says you can edit version constraints in-line, but doesn't mention adding a new dependency.

I only see two uses of printf in ghc:
ghc/InteractiveUI.hs: let nums = map (printf "-%-3d:") [(1::Int)..] compiler/utils/Outputable.lhs: ppr (Fingerprint w1 w2) = text (printf "%016x%016x" w1 w2)
So it seems easy to replace that with some hand-written formatting.
Oh, there are also a bunch of references in libraries/. But it looks like mostly tests for bytestring and dph, so still not too bad.

I think the only references that matter are the ones in base, no? And
there aren't any there that I could find, except Text.Printf itself.
If we lift Text.Printf into a printf package, then make sure that
things reference this package, it should all just compile, I think.
I would vote for trying to do this for 7.8, and only merging my stuff
once it's done. But I'm not willing to manage the move, since I'm not
that Cabal/GHC-literate and haven't dug around in Hackage enough to
know what's affected. Perhaps the biggest objection to this whole plan
is the potentially large amount of packages in Hackage whose .cabal
files need to change: I don't know if there's some easy way to smooth
this transition?
On Tue, Sep 10, 2013 at 2:34 PM, Evan Laforge
I only see two uses of printf in ghc:
ghc/InteractiveUI.hs: let nums = map (printf "-%-3d:") [(1::Int)..] compiler/utils/Outputable.lhs: ppr (Fingerprint w1 w2) = text (printf "%016x%016x" w1 w2)
So it seems easy to replace that with some hand-written formatting.
Oh, there are also a bunch of references in libraries/. But it looks like mostly tests for bytestring and dph, so still not too bad. _______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

i'm actually not aware of many / any? package that use the printf style
approach!
(i could be wrong, but i suspect its not widely used?)
On Thu, Sep 12, 2013 at 2:21 AM, Bart Massey
I think the only references that matter are the ones in base, no? And there aren't any there that I could find, except Text.Printf itself. If we lift Text.Printf into a printf package, then make sure that things reference this package, it should all just compile, I think.
I would vote for trying to do this for 7.8, and only merging my stuff once it's done. But I'm not willing to manage the move, since I'm not that Cabal/GHC-literate and haven't dug around in Hackage enough to know what's affected. Perhaps the biggest objection to this whole plan is the potentially large amount of packages in Hackage whose .cabal files need to change: I don't know if there's some easy way to smooth this transition?
On Tue, Sep 10, 2013 at 2:34 PM, Evan Laforge
wrote: I only see two uses of printf in ghc:
ghc/InteractiveUI.hs: let nums = map (printf "-%-3d:") [(1::Int)..] compiler/utils/Outputable.lhs: ppr (Fingerprint w1 w2) = text (printf "%016x%016x" w1 w2)
So it seems easy to replace that with some hand-written formatting.
Oh, there are also a bunch of references in libraries/. But it looks like mostly tests for bytestring and dph, so still not too bad. _______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

On 2013-09-12 at 08:41:14 +0200, Carter Schonwald wrote:
i'm actually not aware of many / any? package that use the printf style approach! (i could be wrong, but i suspect its not widely used?)
I've done a crude check to see how many latest-version packages on Hackage have .*hs files matching containing the string "Text.Printf": http://lpaste.net/92876 It's still 599 packages that are probably affected by base losing its `Text.Printf` :-/ Maybe we could just deprecated Text.Printf for GHC 7.8, and remove in 7.10 (which may address the big base-split)

Hi, Am Donnerstag, den 12.09.2013, 13:13 +0200 schrieb Herbert Valerio Riedel:
I've done a crude check to see how many latest-version packages on Hackage have .*hs files matching containing the string "Text.Printf":
It's still 599 packages that are probably affected by base losing its `Text.Printf` :-/
Maybe we could just deprecated Text.Printf for GHC 7.8, and remove in 7.10 (which may address the big base-split)
but how many of them depend on base < 4.7? All these will have to modify their build-depends line anyways, so changing it to "base == 4.7.*, printf == 1.0.*" does not seem to be too big of an issue. Greetings, Joachimg -- Joachim “nomeata” Breitner mail@joachim-breitner.de • http://www.joachim-breitner.de/ Jabber: nomeata@joachim-breitner.de • GPG-Key: 0x4743206C Debian Developer: nomeata@debian.org

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
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@cs.pdx.edu
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

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.
:-)
--Bart
On Fri, Sep 6, 2013 at 5:54 AM, Roman Cheplyaka
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
[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@cs.pdx.edu
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

On 06/09/13 04:16, Bart Massey wrote:
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.
You can probably force the `a` to be `()` by using: instance (a ~ ()) => PrintfType (IO a) where ... But that is of course not standard Haskell. Twan

TypeFamilies are kind of heavy machinery here :-), but since it would
be confined to the library and seems to solve the problem, I'd be in
favor of doing as you suggest. We can conditionally compile if we are
worried about non-GHC implementations, I think. Do other folks have an
opinion? --Bart
On Fri, Sep 6, 2013 at 8:18 AM, Twan van Laarhoven
On 06/09/13 04:16, Bart Massey wrote:
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.
You can probably force the `a` to be `()` by using:
instance (a ~ ()) => PrintfType (IO a) where ...
But that is of course not standard Haskell.
Twan
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

A no-extensions approach would be to duplicate the string trick, with an IsUnit class like the IsChar one. However, that's kind of incredibly silly, because fromUnit :: () -> a is pretty much the same as hasAValue :: a, so you get the least specific class ever. Plus there already exist classes which have () as a member. How about: instance Monoid a => PrintfType (IO a) where ... with 'return mempty' instead of 'return undefined'? This is a little bit silly, but lightweight and extensions-free. If you think that mentioning Monoid here is a distraction, feel free to introduce a new class instead. It would end up being roughly speaking the Default class from data-default, which I have gone on record before as calling annoying and useless (with, admittedly, a few limited applications). Here's another idea: just enable FlexibleInstances and use instance PrintfType (IO ()) where ... FlexibleInstances is pretty stable and really the bottom of the hierarchy of class system extensions (perhaps just above FlexibleContexts, but certainly TypeFamilies and MPTCs tend to sort of assume you've got it enabled already). I don't know if there are any inference issues that I'm missing here. On Fri, Sep 06, 2013 at 10:56:55AM -0700, Bart Massey wrote:
TypeFamilies are kind of heavy machinery here :-), but since it would be confined to the library and seems to solve the problem, I'd be in favor of doing as you suggest. We can conditionally compile if we are worried about non-GHC implementations, I think. Do other folks have an opinion? --Bart
On Fri, Sep 6, 2013 at 8:18 AM, Twan van Laarhoven
wrote: On 06/09/13 04:16, Bart Massey wrote:
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.
You can probably force the `a` to be `()` by using:
instance (a ~ ()) => PrintfType (IO a) where ...
But that is of course not standard Haskell.
Twan
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

I already tried FlexibleInstances and the IsUnit typeclass trick and
could get neither to work. AFAICT, both require cooperation from the
caller. I may have just done it wrong, though. I have absolutely no
problem with an IsUnit typeclass if that's a clean solution to the
problem somehow. --Bart
On Sat, Sep 7, 2013 at 5:12 PM, Ben Millwood
A no-extensions approach would be to duplicate the string trick, with an IsUnit class like the IsChar one. However, that's kind of incredibly silly, because fromUnit :: () -> a is pretty much the same as hasAValue :: a, so you get the least specific class ever.
Plus there already exist classes which have () as a member. How about:
instance Monoid a => PrintfType (IO a) where ...
with 'return mempty' instead of 'return undefined'?
This is a little bit silly, but lightweight and extensions-free. If you think that mentioning Monoid here is a distraction, feel free to introduce a new class instead. It would end up being roughly speaking the Default class from data-default, which I have gone on record before as calling annoying and useless (with, admittedly, a few limited applications).
Here's another idea: just enable FlexibleInstances and use
instance PrintfType (IO ()) where ...
FlexibleInstances is pretty stable and really the bottom of the hierarchy of class system extensions (perhaps just above FlexibleContexts, but certainly TypeFamilies and MPTCs tend to sort of assume you've got it enabled already). I don't know if there are any inference issues that I'm missing here.
On Fri, Sep 06, 2013 at 10:56:55AM -0700, Bart Massey wrote:
TypeFamilies are kind of heavy machinery here :-), but since it would be confined to the library and seems to solve the problem, I'd be in favor of doing as you suggest. We can conditionally compile if we are worried about non-GHC implementations, I think. Do other folks have an opinion? --Bart
On Fri, Sep 6, 2013 at 8:18 AM, Twan van Laarhoven
wrote: On 06/09/13 04:16, Bart Massey wrote:
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.
You can probably force the `a` to be `()` by using:
instance (a ~ ()) => PrintfType (IO a) where ...
But that is of course not standard Haskell.
Twan
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

If you are using TypeFamilies then
instance (a ~ ()) => PrintfType (IO a)
would be the way to go.
No silliness with defaulting, no strange classes, no inference woes and it has exactly the right connotation. Once the compiler figures out the outside is IO, then it can assume the argument is ().
On Sep 7, 2013, at 11:01 PM, Bart Massey
I already tried FlexibleInstances and the IsUnit typeclass trick and could get neither to work. AFAICT, both require cooperation from the caller. I may have just done it wrong, though. I have absolutely no problem with an IsUnit typeclass if that's a clean solution to the problem somehow. --Bart
On Sat, Sep 7, 2013 at 5:12 PM, Ben Millwood
wrote: A no-extensions approach would be to duplicate the string trick, with an IsUnit class like the IsChar one. However, that's kind of incredibly silly, because fromUnit :: () -> a is pretty much the same as hasAValue :: a, so you get the least specific class ever.
Plus there already exist classes which have () as a member. How about:
instance Monoid a => PrintfType (IO a) where ...
with 'return mempty' instead of 'return undefined'?
This is a little bit silly, but lightweight and extensions-free. If you think that mentioning Monoid here is a distraction, feel free to introduce a new class instead. It would end up being roughly speaking the Default class from data-default, which I have gone on record before as calling annoying and useless (with, admittedly, a few limited applications).
Here's another idea: just enable FlexibleInstances and use
instance PrintfType (IO ()) where ...
FlexibleInstances is pretty stable and really the bottom of the hierarchy of class system extensions (perhaps just above FlexibleContexts, but certainly TypeFamilies and MPTCs tend to sort of assume you've got it enabled already). I don't know if there are any inference issues that I'm missing here.
On Fri, Sep 06, 2013 at 10:56:55AM -0700, Bart Massey wrote:
TypeFamilies are kind of heavy machinery here :-), but since it would be confined to the library and seems to solve the problem, I'd be in favor of doing as you suggest. We can conditionally compile if we are worried about non-GHC implementations, I think. Do other folks have an opinion? --Bart
On Fri, Sep 6, 2013 at 8:18 AM, Twan van Laarhoven
wrote: On 06/09/13 04:16, Bart Massey wrote:
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.
You can probably force the `a` to be `()` by using:
instance (a ~ ()) => PrintfType (IO a) where ...
But that is of course not standard Haskell.
Twan
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Am 06.09.2013 19:56, schrieb Bart Massey:
TypeFamilies are kind of heavy machinery here :-), but since it would be confined to the library and seems to solve the problem, I'd be in favor of doing as you suggest. We can conditionally compile if we are worried about non-GHC implementations, I think. Do other folks have an opinion? --Bart
The right solution would be to have (>>) :: m () -> m a -> m a. With this type GHC could infer the return type from the fact that the result of printf is unused. However, since it was chosen to be (>>) :: m b -> m a -> m a, we end up with follow-up hacks.

Ah! Suddenly I understand the weird error messages I've been seeing.
Thanks much for the explanation. --Bart
On Sun, Sep 8, 2013 at 9:29 AM, Henning Thielemann
Am 06.09.2013 19:56, schrieb Bart Massey:
TypeFamilies are kind of heavy machinery here :-), but since it would be confined to the library and seems to solve the problem, I'd be in favor of doing as you suggest. We can conditionally compile if we are worried about non-GHC implementations, I think. Do other folks have an opinion? --Bart
The right solution would be to have (>>) :: m () -> m a -> m a.
With this type GHC could infer the return type from the fact that the result of printf is unused.
However, since it was chosen to be (>>) :: m b -> m a -> m a, we end up with follow-up hacks.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
participants (14)
-
Bardur Arantsson
-
Bart Massey
-
Ben Millwood
-
Bryan O'Sullivan
-
Carter Schonwald
-
Christopher Done
-
Edward Kmett
-
Evan Laforge
-
Gershom Bazerman
-
Henning Thielemann
-
Herbert Valerio Riedel
-
Joachim Breitner
-
Roman Cheplyaka
-
Twan van Laarhoven