From: Xavier Leroy <xleroy@pauillac.inria.fr>
To: thomas.k.bond@cpmx.saic.com (T. Kurt Bond)
Cc: caml-list@pauillac.inria.fr, tkb@wvlink.mpl.com
Subject: Re: string variables in Printf.* calls: Bug, or lack of understanding?
Date: Tue, 18 Feb 1997 17:39:40 +0100 (MET) [thread overview]
Message-ID: <199702181639.RAA28850@pauillac.inria.fr> (raw)
In-Reply-To: <199702131831.NAA22295@abetti> from "T. Kurt Bond" at "Feb 13, 97 01:31:02 pm"
> Objective Caml version 1.03
>
> [1] # let s = "%f" in Printf.printf s 10.5;;
> Characters 30-31:
> This expression has type string but is here used with type
> ('a, out_channel, unit) format
>
> [2] # Printf.printf "%f" 10.5;;
> 10.500000- : unit = ()
>
> I don't understand why the variable s, which is bound to a string value,
> causes the error in statement 1, while using a literal string in
> statement 2 works as expected. Can anyone explain? Or is this a bug?
It's a feature: format strings are typed specially in order to make
printf type-safe. Look at the type for Printf.printf: it's
('a, out_channel, unit) format -> ...
and not
string -> ...
A format string is typed specially and receives a type of the form
(t1, t2, t3) format, for suitable types t1, t2, t3. For instance, the
format string ``%f %d'' has type
(float -> int -> 'b, 'c, 'b) format
which, when passed as first argument to Printf.printf, gives the
return type
float -> int -> unit
which ensures that the next two arguments are a float and an integer,
as expected.
Now comes the dirty hack. In an ideal world, there would be a
different syntax for string literals and for format literals, so that
the type-checker would always know whether to type the literal as a
string or as a format.
For backward compatibility, and because we are somehow running out of
quote characters, format literals have actually the same syntax as
strings, and it's the type expected by the context of the literal that
says whether to type it as a string or as a format. In some sense, the
syntax for string literals is overloaded for format literals as well.
In particular, when a string literal occur as first argument to
Printf.printf (your example [2]), its expected type is ('a,
out_channel, unit) format and thus the type-checker types it as a
format literal. In other contexts, such as your example [1] above,
there is no expected type and the literal is therefore typed as a
string.
However, you can force the correct behavior with a type constraint:
let s = ("%f" : ('a, 'b, 'c) format) in Printf.printf s 10.5;;
You can actually go quite far this way, and use formats as first-class
values (pass them as arguments to functions, etc) -- all in a
type-safe way. Just remember to put a type constraint around format
literals if the context does not already expect a format type.
- Xavier Leroy
next prev parent reply other threads:[~1997-02-18 17:39 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
1997-02-13 18:31 T. Kurt Bond
1997-02-18 16:39 ` Xavier Leroy [this message]
1997-02-24 20:40 Valentin Bonnard
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=199702181639.RAA28850@pauillac.inria.fr \
--to=xleroy@pauillac.inria.fr \
--cc=caml-list@pauillac.inria.fr \
--cc=thomas.k.bond@cpmx.saic.com \
--cc=tkb@wvlink.mpl.com \
/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