caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* ocaml 2.02 bug: curried printf
@ 1999-03-06  1:38 William Chesters
  1999-03-12 15:00 ` Xavier Leroy
  0 siblings, 1 reply; 10+ messages in thread
From: William Chesters @ 1999-03-06  1:38 UTC (permalink / raw)
  To: caml-list

This used to work in 2.01, but 2.02 outputs the wrong thing:

Cette programme-ci a fonctionné correctement avec 2.01; avec 2.02 non
plus:

	open Printf
	open List
	open String

	let udt = [1; 2; 3] ;;

	print_endline (concat " " (map (sprintf "foo%d") udt)) ;;
	print_endline (concat " " (map (fun s -> sprintf "foo%d" s) udt)) ;;

	iter (printf "foo%d") udt; print_newline () ;;
	iter (fun s -> printf "foo%d" s) udt; print_newline ()



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: ocaml 2.02 bug: curried printf
  1999-03-06  1:38 ocaml 2.02 bug: curried printf William Chesters
@ 1999-03-12 15:00 ` Xavier Leroy
  1999-03-12 15:31   ` William Chesters
  1999-03-19  8:47   ` another approach to sprintf (Re: ocaml 2.02 bug: curried printf) Eijiro Sumii
  0 siblings, 2 replies; 10+ messages in thread
From: Xavier Leroy @ 1999-03-12 15:00 UTC (permalink / raw)
  To: William Chesters, caml-list

> This used to work in 2.01, but 2.02 outputs the wrong thing:

You're right that sprintf in 2.02 is broken w.r.t. partial application.
However, even after fixing the obvious bug, it might not do what you want.

The behavior of the *printf functions when partially applied
has always been a bit strange even before 2.02: sprintf did "the right
thing", but printf prints as much as it can without needing the
omitted arguments, then resumes printing when more arguments are
provided.  In your examples:

> 	let udt = [1; 2; 3] ;;
> 	iter (printf "foo%d") udt; print_newline () ;;

This prints "foo123" because the printing of "foo" was ``factored out''.

> 	iter (fun s -> printf "foo%d" s) udt; print_newline ()

This prints "foo1foo2foo3" because printf is no longer partially applied.

For sprintf, the old implementation was purely functional (a list of
string fragments is built, then concatenated), hence partial
application made no difference:

> 	map (sprintf "foo%d") udt
>       map (fun s -> sprintf "foo%d" s) udt

both return ["foo1"; "foo2"; "foo3"].

The new implementation of sprintf is based on an internal extensible
buffer, hence works by side-effects (just like printf, actually).
Hence, after fixing the obvious bug, we'd get the same "print as much
as possible" behavior that printf displays, thus

        let f = sprintf "foo%d" in
        let r1 = f 1 in
        let r2 = f 2 in
        (r1, r2)

would return ("foo1", "2"), while

        (sprintf "foo%d" 1, sprint "foo%d" 2)

still returns ("foo1", "foo2").

We can go back to the 2.01 implementation of sprintf, of course, but
it's less efficient than the one based on extensible buffers, and also
prevents interesting code sharing between sprintf and bprintf.

The alternative is to keep a buffer-based sprintf that is efficient
and consistent with printf ("consistent" in the sense of "as weird as"),
but is not really usable in partial application contexts.

Any opinions?

- Xavier Leroy




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: ocaml 2.02 bug: curried printf
  1999-03-12 15:00 ` Xavier Leroy
@ 1999-03-12 15:31   ` William Chesters
  1999-03-19  8:47   ` another approach to sprintf (Re: ocaml 2.02 bug: curried printf) Eijiro Sumii
  1 sibling, 0 replies; 10+ messages in thread
From: William Chesters @ 1999-03-12 15:31 UTC (permalink / raw)
  To: caml-list

Xavier Leroy writes:
 > The behavior of the *printf functions when partially applied
 > has always been a bit strange even before 2.02: [...]

Ooooh yes, I never noticed that ...

 > The alternative is to keep a buffer-based sprintf that is efficient
 > and consistent with printf ("consistent" in the sense of "as weird as"),
 > but is not really usable in partial application contexts.
 > 
 > Any opinions?

The change in behaviour was a nuisance to me (and I now have a module
called Printf201!).  In spite of that I'd be happy to stick with the
new semantics if it's more efficient.  I say that becase I believe the
reason I used constructs like

       concat " " (Array.map (sprintf "...") xs)

, for generating C code and string representations of complex objects,
was precisely because of the lack of extensible string buffers.  With
Buffer available I would be more likely to use a `for' loop with
`bprintf' (or indeed `Format.bprintf').




^ permalink raw reply	[flat|nested] 10+ messages in thread

* another approach to sprintf (Re: ocaml 2.02 bug: curried printf)
  1999-03-12 15:00 ` Xavier Leroy
  1999-03-12 15:31   ` William Chesters
@ 1999-03-19  8:47   ` Eijiro Sumii
  1999-03-23 16:17     ` Xavier Leroy
  1 sibling, 1 reply; 10+ messages in thread
From: Eijiro Sumii @ 1999-03-19  8:47 UTC (permalink / raw)
  To: caml-list

Hello,

(Excuse me for changing the subject and providing no French
version...)

I don't know very much about *printf in ocaml, but how about Olivier
Danvy's approach to sprintf (http://www.brics.dk/RS/98/12/index.html)?
It seems safer and faster than ordinary "interpretive" approach.  I'd
like to hear what do you (I mean, readers of this mailing list) think
about it.

> Subject: Re: ocaml 2.02 bug: curried printf
> From: Xavier Leroy <Xavier.Leroy@inria.fr>
> Date: Fri, 12 Mar 1999 16:00:17 +0100
...
> We can go back to the 2.01 implementation of sprintf, of course, but
> it's less efficient than the one based on extensible buffers, and also
> prevents interesting code sharing between sprintf and bprintf.
> 
> The alternative is to keep a buffer-based sprintf that is efficient
> and consistent with printf ("consistent" in the sense of "as weird as"),
> but is not really usable in partial application contexts.
> 
> Any opinions?

// Eijiro Sumii <sumii@yl.is.s.u-tokyo.ac.jp>
// 
// Kobayashi Laboratory, Department of Information Science,
// Graduate School of Science, University of Tokyo




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: another approach to sprintf (Re: ocaml 2.02 bug: curried printf)
  1999-03-19  8:47   ` another approach to sprintf (Re: ocaml 2.02 bug: curried printf) Eijiro Sumii
@ 1999-03-23 16:17     ` Xavier Leroy
  1999-03-24 19:37       ` John Prevost
  1999-03-24 23:48       ` Frank A. Christoph
  0 siblings, 2 replies; 10+ messages in thread
From: Xavier Leroy @ 1999-03-23 16:17 UTC (permalink / raw)
  To: Eijiro Sumii, caml-list

> I don't know very much about *printf in ocaml, but how about Olivier
> Danvy's approach to sprintf (http://www.brics.dk/RS/98/12/index.html)?
> It seems safer and faster than ordinary "interpretive" approach.  I'd
> like to hear what do you (I mean, readers of this mailing list) think
> about it.

It's a cute trick.  One drawback is that the format is not a character
string, but needs to be expressed using special functions and infix
operators.  On the other hand, it doesn't need the special
typechecking rules for format strings that we have in OCaml.

With this special typechecking rules, I don't think Danvy's "partially
evaluated" printf is any safer than OCaml's "interpreted" printf.

Also, it doesn't solve (nor makes any worse) the issues with partial
application of printf and friends that we discussed before.

- Xavier Leroy




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: another approach to sprintf (Re: ocaml 2.02 bug: curried printf)
  1999-03-23 16:17     ` Xavier Leroy
@ 1999-03-24 19:37       ` John Prevost
  1999-03-25 13:29         ` Christian Lindig
  1999-03-29 16:31         ` Xavier Leroy
  1999-03-24 23:48       ` Frank A. Christoph
  1 sibling, 2 replies; 10+ messages in thread
From: John Prevost @ 1999-03-24 19:37 UTC (permalink / raw)
  To: caml-list

Xavier Leroy <Xavier.Leroy@inria.fr> writes:

> It's a cute trick.  One drawback is that the format is not a character
> string, but needs to be expressed using special functions and infix
> operators.  On the other hand, it doesn't need the special
> typechecking rules for format strings that we have in OCaml.
> 
> With this special typechecking rules, I don't think Danvy's "partially
> evaluated" printf is any safer than OCaml's "interpreted" printf.
> 
> Also, it doesn't solve (nor makes any worse) the issues with partial
> application of printf and friends that we discussed before.

It does, however, mean that people can extend the set of patterns that
can be used in printf in a more palatable way than the %a mechanism.
Especially with neat things like Danvy's "lis" combinator.

It also allows me to take two formats and concatenate them, like this:

let foo = int $ lit " " $ int $ string
let bar = lis int $ lit "!"
let zum = foo $ bar

which you can't do with O'Caml's format strings.  (I tried to hack
something to do this once, using Obj.magic as the Printf module does.
I wasn't able to come up with anything, but I may be able to now that
I've had more experience looking at things like Danvy's printf.)

John.




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: another approach to sprintf (Re: ocaml 2.02 bug: curried printf)
  1999-03-23 16:17     ` Xavier Leroy
  1999-03-24 19:37       ` John Prevost
@ 1999-03-24 23:48       ` Frank A. Christoph
  1 sibling, 0 replies; 10+ messages in thread
From: Frank A. Christoph @ 1999-03-24 23:48 UTC (permalink / raw)
  To: caml-list

> > I don't know very much about *printf in ocaml, but how about Olivier
> > Danvy's approach to sprintf (http://www.brics.dk/RS/98/12/index.html)?
> > It seems safer and faster than ordinary "interpretive" approach.  I'd
> > like to hear what do you (I mean, readers of this mailing list) think
> > about it.
> 
> It's a cute trick.  One drawback is that the format is not a character
> string, but needs to be expressed using special functions and infix
> operators.  On the other hand, it doesn't need the special
> typechecking rules for format strings that we have in OCaml.
> 
> With this special typechecking rules, I don't think Danvy's "partially
> evaluated" printf is any safer than OCaml's "interpreted" printf.

However, it has the significant advantage that formats are user-extensible.

> Also, it doesn't solve (nor makes any worse) the issues with partial
> application of printf and friends that we discussed before.

--FC



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: another approach to sprintf (Re: ocaml 2.02 bug: curried printf)
  1999-03-24 19:37       ` John Prevost
@ 1999-03-25 13:29         ` Christian Lindig
  1999-03-25 20:52           ` John Prevost
  1999-03-29 16:31         ` Xavier Leroy
  1 sibling, 1 reply; 10+ messages in thread
From: Christian Lindig @ 1999-03-25 13:29 UTC (permalink / raw)
  To: John Prevost; +Cc: caml-list

    +-- Xavier Leroy
    | It's a cute trick. One drawback is that the format is not a
    | character string, but needs to be expressed using special
    | functions and infix operators.

    +-- John Prevost
    | It does, however, mean that people can extend the set of patterns
    | that can be used in printf in a more palatable way than the
    | %a mechanism. Especially with neat things like Danvy's "lis"
    | combinator.

The suggested functional approach to printf has another possible
drawback:  when you want to express all the options like "%5.5f"
possible in C style printf formatting you need a whole bunch of
functions.  Since OCaml has no overloading a single `float' function
for floats can not capture them all. 

-- Christian

-- 
 Christian Lindig   Technische Universitaet Braunschweig, Germany
                    http://www.cs.tu-bs.de/softech/people/lindig
                    lindig@ips.cs.tu-bs.de




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: another approach to sprintf (Re: ocaml 2.02 bug: curried printf)
  1999-03-25 13:29         ` Christian Lindig
@ 1999-03-25 20:52           ` John Prevost
  0 siblings, 0 replies; 10+ messages in thread
From: John Prevost @ 1999-03-25 20:52 UTC (permalink / raw)
  To: caml-list

Christian Lindig <lindig@ips.cs.tu-bs.de> writes:

> The suggested functional approach to printf has another possible
> drawback:  when you want to express all the options like "%5.5f"
> possible in C style printf formatting you need a whole bunch of
> functions.  Since OCaml has no overloading a single `float' function
> for floats can not capture them all. 

Yes, but you can still get the formatting features you want by having
both formats that take arguments (like "lit") and also higher-order
formats (for example, a format which truncates whatever format it is
given to a specific string length, or a format that right justifies
within a certain length, or etc.)

In fact, the system is more powerful precisely because you can do
things like this to extend the system.  Not only can you do %5.5f, you
could also make something to display the float in binary, or to
display the fraction as a vulgar fraction symbol (i.e. ½).

John.




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: another approach to sprintf (Re: ocaml 2.02 bug: curried printf)
  1999-03-24 19:37       ` John Prevost
  1999-03-25 13:29         ` Christian Lindig
@ 1999-03-29 16:31         ` Xavier Leroy
  1 sibling, 0 replies; 10+ messages in thread
From: Xavier Leroy @ 1999-03-29 16:31 UTC (permalink / raw)
  To: John Prevost, caml-list

> It does, however, mean that people can extend the set of patterns that
> can be used in printf in a more palatable way than the %a mechanism.
> Especially with neat things like Danvy's "lis" combinator.

This is a good point.

> It also allows me to take two formats and concatenate them, like this:
> let foo = int $ lit " " $ int $ string
> let bar = lis int $ lit "!"
> let zum = foo $ bar
> which you can't do with O'Caml's format strings.

You almost can.  The following definition works as long as you
don't have %a and %t escapes in your format strings:

let (^^) (s1 : ('a, 'b, 'c) format) (s2 : ('c, 'b, 'd) format) =
  (Obj.magic (Obj.magic s1 ^ Obj.magic s2) : ('a, 'b, 'd) format)

If you have occurrences of %a or %t in s1, the typing becomes wrong.
This could be fixed by adding a fourth type parameter to the "format"
type constructor, but I agree this is getting really complicated.

- Xavier Leroy




^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~1999-03-29 18:05 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-03-06  1:38 ocaml 2.02 bug: curried printf William Chesters
1999-03-12 15:00 ` Xavier Leroy
1999-03-12 15:31   ` William Chesters
1999-03-19  8:47   ` another approach to sprintf (Re: ocaml 2.02 bug: curried printf) Eijiro Sumii
1999-03-23 16:17     ` Xavier Leroy
1999-03-24 19:37       ` John Prevost
1999-03-25 13:29         ` Christian Lindig
1999-03-25 20:52           ` John Prevost
1999-03-29 16:31         ` Xavier Leroy
1999-03-24 23:48       ` Frank A. Christoph

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).