Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Xavier Leroy <Xavier.Leroy@inria.fr>
To: William Chesters <williamc@dai.ed.ac.uk>, caml-list@inria.fr
Subject: Re: ocaml 2.02 bug: curried printf
Date: Fri, 12 Mar 1999 16:00:17 +0100	[thread overview]
Message-ID: <19990312160017.60444@pauillac.inria.fr> (raw)
In-Reply-To: <199903060138.BAA13133@toy.william.bogus>; from William Chesters on Sat, Mar 06, 1999 at 01:38:18AM +0000

> 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




  reply	other threads:[~1999-03-12 17:07 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-03-06  1:38 William Chesters
1999-03-12 15:00 ` Xavier Leroy [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=19990312160017.60444@pauillac.inria.fr \
    --to=xavier.leroy@inria.fr \
    --cc=caml-list@inria.fr \
    --cc=williamc@dai.ed.ac.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox