Re: [Haskell-cafe] Re: Pure Haskell Printf

2004-11-17 Thread Jan-Willem Maessen

Scott Turner wrote:
On 2004 November 16 Tuesday 06:42, Jérémy Bobbio wrote:
 

There is a probleme with ShowS though: it is not internationalizable at
all.  Strings like printf's or with any kind of variable substitution is
required for proper internationalization / localization.
   

Printf is not adequate for internationalization either, because word (and thus 
parameter) ordering may vary among languages.  Note that MissingH.Printf 
addresses this with a feature which supports keys in format items, e.g. 
%(item1)s.

This is what it boils down to for me.  A post by Malcolm Wallace to one 
of the Haskell lists a few years back convinced me that:

Internationalization is a killer application for printf-style 
format-string-based functions.

I have seen approximately 32767 different proposals for printf with 
strong static typechecking, using anything from specialized data types 
to depedently-typed functions to compile-time reflection.

None of these appears to be able to solve the simple problem of allowing 
localization (or general fiddling with the formatting) without 
recompiling and relinking.  In that respect there will always be a place 
for dynamically-checked printf, and John's library really seems to be 
doing The Right Thing.

I remain much more skeptical that there's a need for a 
statically-checked printf which uses format strings.  ShowS and related 
approaches work pretty well in my experience (though it'd be nice to see 
standardized support for flexible number formatting).

A Challenge To The Type System Hackers: Is there a way to get the best 
of both worlds?  To do static checking on format strings when they're 
available, but fall back to dynamic checking when they are not?  Perhaps 
we provide a canonical format string, or use some other sort of hackery, 
and then check the actual string dynamically.

-Jan-Willem Maessen
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Pure Haskell Printf

2004-11-17 Thread John Goerzen
On 2004-11-17, Vincenzo Ciancia [EMAIL PROTECTED] wrote:
 On Tuesday 16 November 2004 10:37, Henning Thielemann wrote:
 Variable length argument lists are really a mess. Why are people so
 keen on them? What is the advantage over a plain list as single
 argument? Is vsprintf %s, your age is %s\n [John, show
 (10::Integer)] really too complicated?

 The implementation of printf in ocaml, for example, is not only 
 type-safe, but more type safe than passing a list, because the number 
 and type of arguments is known at compile time.

On the other hand, the OCaml printf is, unless I'm very mistaken,
handled specially by the compiler.  That is, the compiler looks out for
format strings and converts them to the weirdo format4 things that OCaml
uses.

That means that one could not implement one's own printf using pure
OCaml.  Though a person could use camlp4, but then that's back to the
same place as TH.

OCaml's printf also is limited in that it can take only a string literal
for the format string, and not a string in a variable.

-- John

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Pure Haskell Printf

2004-11-16 Thread Peter Simons
Henning Thielemann writes:

  Variable length argument lists are really a mess. Why are
  people so keen on them?

One advantage is that you need to type fewer characters.
It's, well, not _that_ important, I'll readily admit. :-)
But

  vsnprintf i = %d;\tj = %s 12 test

is more compact than any other notation I'd be aware of. And
it comes, of course, at the price of being rather dangerous,
depending on what you do.

Personally, I have found ShowS style text-formatting to be
my favorite. The code

  verb = showString
  msg  = (verb i = ) . (12 `shows`) . (verb \tj = ) $ test

isn't mind-blowingly compact either, but I always feel an
odd satisfaction when writing this, because it's supposedly
very efficient -- which justifies the extra characters,
IMHO. :-)

Peter

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Pure Haskell Printf

2004-11-16 Thread Henning Thielemann

On 16 Nov 2004, Peter Simons wrote:

 Henning Thielemann writes:
 
   Variable length argument lists are really a mess. Why are
   people so keen on them?
 
 One advantage is that you need to type fewer characters.

I know memory is expensive, that's why only the last two digits of year
numbers are stored. :-]

 It's, well, not _that_ important, I'll readily admit. :-)

I'm afraid, that's the only reason. :-(

 Personally, I have found ShowS style text-formatting to be
 my favorite. The code
 
   verb = showString
   msg  = (verb i = ) . (12 `shows`) . (verb \tj = ) $ test
 
 isn't mind-blowingly compact either, but I always feel an
 odd satisfaction when writing this, because it's supposedly
 very efficient -- which justifies the extra characters,

You can save even more characters:

msg  = verb i =  . shows 12 . verb \tj =  $ test

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Pure Haskell Printf

2004-11-16 Thread Keean Schupke
At the risk of getting off topic... the reason 'C' has printf is because 
it is not
polymorphic. Printf is a hack to allow different types to be printed 
out, such that
they did not need printInt, printFloat etc. Remember C is typesafe, so 
the only
way they could do this was to pass the first argument (the format string) to
extract the types of the following arguments. Haskell doesn't need such 
tricks
as it is polymorphic, we can just use 'show' no matter what the type is.

Keean.
Peter Simons wrote:
Henning Thielemann writes:
 One advantage is that you need to type fewer characters.
 I know memory is expensive, that's why only the last two
 digits of year numbers are stored. :-]
I understand what you're getting at -- and I find it
annoying, too, when people sacrifice robustness for comfort.
I'm not sure, though, whether this is the case here, because
vsnprintf in Haskell still is type-safe. You'll get more
complicated error messages, the memory footprint might be
worse, but it still _is_ robust code.
Perhaps it really is a matter of personal taste.
Just for the sake of seeing the point from all possible
perspectives, I could think of another reason why you might
need a function like that: If you want to provide
printf-style variable substitutions to the user, say in a
config file. People are _used_ to this mechanism, and many
programs I know offer this feature to customize text
templates, etc. It can't hurt to have a function that does
the parse job and returns the result for you.
Although, if you think this through, you'll soon arrive at
the conclusion that for this particular use-case hard-coded
place-holders (like %s, %d, etc.) are not that useful. You'd
like to be able to (easily!) extend the function, to offer a
more general variable substitution, like sh(1) does. So that
you could write
 Dear ${customer},
 are you interested in making ${phantasy-number} fast?
and pass a function (String - a) to vsnprintf which does
the lookup. I'm not sure how having different types of
values in the dictionary plays into this, though.
 You can save even more characters:
 msg  = verb i =  . shows 12 . verb \tj =  $ test
Right! One more reason to use ShowS-style. :-)
Peter
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe
 

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Pure Haskell Printf

2004-11-16 Thread Andreas Rossberg
Keean Schupke wrote:
Remember C is typesafe
In which parallel universe?
--
Andreas Rossberg, [EMAIL PROTECTED]
Let's get rid of those possible thingies!  -- TB
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Pure Haskell Printf

2004-11-16 Thread Jon Fairbairn
On 2004-11-16 at 11:42+0100 Peter Simons wrote:
 Henning Thielemann writes:
 
   One advantage is that you need to type fewer characters.
 
   I know memory is expensive, that's why only the last two
   digits of year numbers are stored. :-]
 
 I understand what you're getting at -- and I find it
 annoying, too, when people sacrifice robustness for comfort.
 
 I'm not sure, though, whether this is the case here, because
 vsnprintf in Haskell still is type-safe.


Not statically, though, surely? 

 vsprintf %d, your age is %s\n John (10::Integer)

is type incorrect, but won't be reported at compile time. At
least I can't see how it could be, given that the string
can't be dissected at compile time.

   You can save even more characters:
 
   msg  = verb i =  . shows 12 . verb \tj =  $ test
 
 Right! One more reason to use ShowS-style. :-)

and that really is type safe.


-- 
Jón Fairbairn [EMAIL PROTECTED]


___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Pure Haskell Printf

2004-11-16 Thread Keean Schupke
Andreas Rossberg wrote:
Keean Schupke wrote:
Remember C is typesafe
In which parallel universe?
I of course meant strongly-typed, you cannot pass a pointer to an int 
where a pointer
to a float is required ... modern C compilers require you to explicitly 
cast. Where
it fell down was all that automatic type promotion, and providing unsafe 
casts.

There is now a typesafe 'C', but I can't remember what it is called - 
presumably it uses some kind of linear-alias typing to make pointers safe.

Keean.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Pure Haskell Printf

2004-11-16 Thread Keean Schupke
Actually it can be statically checked, as the string is a constant, we can
lift it to a type (at the moment we would have to use template haskell - but
there is no reason the compiler cannot be a little more aggresive in 
applying
functions to constants at compile time, in which case we can use 
polymorphic
recursion)... So the format string can be lifted to something like:

format :: HCons (ConstString (HCons ParString (HCons ParInt HNil)))
we can then construct a class to recurse on this type checking each of the
'Par...' types against the argument to ensure the type is correct. The code
would look like Oleg's variable argument function code with an additional
class parameter for the format-type.
   Keean.
Henning Thielemann wrote:
On 16 Nov 2004, Peter Simons wrote:
 

I'm not sure, though, whether this is the case here, because
vsnprintf in Haskell still is type-safe. You'll get more
complicated error messages, the memory footprint might be
worse, but it still _is_ robust code.
   

Yes and no. It can't be checked statically if the number of placeholders
matches the number of arguments. It can't be checked statically if the
types of placeholders match the types of arguments. It is not possible to
create functions with more than one variable length parameter lists.
 

 Dear ${customer},
 are you interested in making ${phantasy-number} fast?
and pass a function (String - a) to vsnprintf which does
the lookup. I'm not sure how having different types of
values in the dictionary plays into this, though.
   

The function MissingH.Printf.sprintf is probably the better choice, but
one could even replace [Value] by [String]. The conversion from any type
to String can be easily done using 'show' by the caller. Though it gives
the author of the format string less control over the formatting of
particular types like numbers.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe
 

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Pure Haskell Printf

2004-11-16 Thread David Roundy
On Tue, Nov 16, 2004 at 12:21:41PM +0100, Henning Thielemann wrote:
 The function MissingH.Printf.sprintf is probably the better choice, but
 one could even replace [Value] by [String]. The conversion from any type
 to String can be easily done using 'show' by the caller. Though it gives
 the author of the format string less control over the formatting of
 particular types like numbers.

It seems to me that control over formatting of numbers is the only reason
to use anything printf-like... but perhaps that's just because of the
frequency with which I print (and read) doubles.
-- 
David Roundy
http://www.darcs.net
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Pure Haskell Printf

2004-11-16 Thread Ben Rudiak-Gould
Keean Schupke wrote:
 At the risk of getting off topic... the reason 'C' has printf is because
 it is not polymorphic. Printf is a hack to allow different types to be
 printed out, such that they did not need printInt, printFloat etc.
Many language have printf-like functions despite not satisfying this
criterion. Perl, Python, and Common Lisp are the three that come to mind.
I think the reason they have it is that it's useful in general to be able
to visually separate the string template from the expressions being
printed. Even (name++, your age is++age++.) is pretty punctuation-heavy
for a template. (Plus, it has a bug in it, which would be much easier to
see in the printf syntax.)
-- Ben
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Pure Haskell Printf

2004-11-16 Thread Peter Simons
Jon Fairbairn writes:

  vsprintf %d, your age is %s\n John (10::Integer)

  is type incorrect, but won't be reported at compile time.

Hmmm. Right. You'd need Template Haskell for that.

I see.

Peter

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Pure Haskell Printf

2004-11-16 Thread Matthew Walton
Ben Rudiak-Gould wrote:
Keean Schupke wrote:
  At the risk of getting off topic... the reason 'C' has printf is because
  it is not polymorphic. Printf is a hack to allow different types to be
  printed out, such that they did not need printInt, printFloat etc.
Many language have printf-like functions despite not satisfying this
criterion. Perl, Python, and Common Lisp are the three that come to mind.
I think the reason they have it is that it's useful in general to be able
to visually separate the string template from the expressions being
printed. Even (name++, your age is++age++.) is pretty punctuation-heavy
for a template. (Plus, it has a bug in it, which would be much easier to
see in the printf syntax.)
Perl, as I see it, has printf for two reasons. The first is because 
sometimes

printf something%dsomething else, $number;
is nicer to deal with than
print something${number}something else;
but I think primarily because printf lets you specify the number 
formatting and other such things, which Perl's variable interpolation 
system won't. Things like

printf %02d, $number;
Are invaluable at times. That, as I see it, is the value of printf-like 
functions. It's certainly preferable (no matter how painful to the parts 
of us which like nice clean pure code) to C++'s rather unpleasant 
iostreams system of throwing random objects down a stream to change the 
number formatting pattern. Ugh.

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Pure Haskell Printf

2004-11-16 Thread Andreas Rossberg
Keean Schupke wrote:

I of course meant strongly-typed, you cannot pass a pointer to an int 
where a pointer
to a float is required ... modern C compilers require you to explicitly 
cast.
According to the C standard,
  void f(float *p) { *p + 1.0; }
  void g(void *p) { f(p); }
  void h(int n) { g(n); }
is perfectly valid (though undefined).
Where
it fell down was all that automatic type promotion, and providing unsafe 
casts.
And other things, like unions, varargs, etc. Not to speak of subtyping 
in C++...

There is now a typesafe 'C', but I can't remember what it is called - 
presumably it uses some kind of linear-alias typing to make pointers safe.
Do you mean Cyclone?
  http://www.research.att.com/projects/cyclone/
Cheers,
- Andreas
--
Andreas Rossberg, [EMAIL PROTECTED]
Let's get rid of those possible thingies!  -- TB
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Pure Haskell Printf

2004-11-16 Thread MR K P SCHUPKE
Of course you can do intertationalisation with show... There is a
paper on using type classes to define implicit confugurations,
perhasps someone can provide the reference? 

This can be used to nicely redefine show... Ill see if I cant 
dig out an example.

Keean.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Pure Haskell Printf

2004-11-16 Thread Scott Turner
On 2004 November 16 Tuesday 06:42, Jérémy Bobbio wrote:
 There is a probleme with ShowS though: it is not internationalizable at
 all.  Strings like printf's or with any kind of variable substitution is
 required for proper internationalization / localization.
Printf is not adequate for internationalization either, because word (and thus 
parameter) ordering may vary among languages.  Note that MissingH.Printf 
addresses this with a feature which supports keys in format items, e.g. 
%(item1)s.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Pure Haskell Printf

2004-11-16 Thread John Goerzen
On 2004-11-16, Henning Thielemann [EMAIL PROTECTED] wrote:
 On 16 Nov 2004, Peter Simons wrote:

 Yes and no. It can't be checked statically if the number of placeholders
 matches the number of arguments. It can't be checked statically if the
 types of placeholders match the types of arguments. It is not possible to
 create functions with more than one variable length parameter lists.

That's a particular problem, since this was one of the motivations for
getting a printf out there.  It makes a very nice way to produce nice
column-aligned data from a variety of numeric and string sources, and
provides a good deal of control over numeric output formats, too.

If I encounter %07.3f, I can't just do a read on a string passed to me,
hoping that I'd get a valid Double (or Rational or whatever).  One of
the annoying things is that show on a Rational produces a value that is
incompatible with show on a Double, and the read functions for these two
types can't understand each other's string formats.  (Urg.)

 and pass a function (String - a) to vsnprintf which does
 the lookup. I'm not sure how having different types of
 values in the dictionary plays into this, though.

There is a function like that in the MissingH.Printf source, but it is
not exported at present (rather it is used to support the association
list and FiniteMap versions of this feature).  It could easily be
exported, though.

-- John


___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Pure Haskell Printf

2004-11-16 Thread John Goerzen
On 2004-11-16, Peter Simons [EMAIL PROTECTED] wrote:
  I know memory is expensive, that's why only the last two
  digits of year numbers are stored. :-]

 I understand what you're getting at -- and I find it
 annoying, too, when people sacrifice robustness for comfort.

In this particular case, the printf functions without the leading v
operate on a list in the manner some have suggested.

I find the v forms preferable since they are easier to type, though I
understand the case against them.

 the conclusion that for this particular use-case hard-coded
 place-holders (like %s, %d, etc.) are not that useful. You'd
 like to be able to (easily!) extend the function, to offer a
 more general variable substitution, like sh(1) does. So that
 you could write

   Dear ${customer},

Indeed, I've already done that in the Python style.  From [1]:


-
As a special extension to the printf() format string syntax, special
functions can take a key name in the format string. This key will then
be looked up in an association list or FiniteMap passed in. Python
programmers will find this very similar to Python's % operator, which
can look up inside dicts. 




Here's an example: 

import MissingH.Printf

al = [(item1, v Test One),
  (blah, v (5::Int)),
  (zip, v (3.14::Float))]

main :: IO ()
main = do
   printfAL %(item1)s: %(blah)03d, %(zip)06.3f; %(item1)s\n al


This will print: 

Test One: 005, 03.140; Test One
---

There are also printfFM functions that work with FiniteMaps in a similar
manner.

[1] http://gopher.quux.org:70/devel/missingh/html/MissingH.Printf.html#6

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Pure Haskell Printf

2004-11-16 Thread John Goerzen
On 2004-11-16, Jon Fairbairn [EMAIL PROTECTED] wrote:
 On 2004-11-16 at 11:42+0100 Peter Simons wrote:
 I'm not sure, though, whether this is the case here, because
 vsnprintf in Haskell still is type-safe.


 Not statically, though, surely? 

 vsprintf %d, your age is %s\n John (10::Integer)

 is type incorrect, but won't be reported at compile time. At
 least I can't see how it could be, given that the string
 can't be dissected at compile time.

You are correct.  One of the drawbacks of doing this in pure Haskell is
that you lose compile-time type checking.  The above code will throw an
exception at runtime.

Ian Lynagh's Template Haskell-based Printf doesn't suffer from that
problem, since it can generate the appropriate Haskell code at compile
time.  On the other hand, it is less portable.  So not all printf
implementations for Haskell have this problem.

So, people have an option.  That's my intent.

-- John

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Pure Haskell Printf

2004-11-16 Thread Keith Wansbrough
 On 2004 November 16 Tuesday 06:42, Jérémy Bobbio wrote:
  There is a probleme with ShowS though: it is not internationalizable at
  all.  Strings like printf's or with any kind of variable substitution is
  required for proper internationalization / localization.
 Printf is not adequate for internationalization either, because word (and 
 thus 
 parameter) ordering may vary among languages.

POSIX / SUS 2001 printf() supports positional arguments, like this:

printf(%2$d %1$s\n,days of christmas,12);

This is required for l10n, as you say..

--KW 8-)
-- 
Keith Wansbrough [EMAIL PROTECTED]
http://www.cl.cam.ac.uk/users/kw217/
University of Cambridge Computer Laboratory.

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe