<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE message PUBLIC
  "-//MLarc//DTD MLarc output files//EN"
  "../../mlarc.dtd"[
  <!ATTLIST message
    listname CDATA #REQUIRED
    title CDATA #REQUIRED
  >
]>

  <?xml-stylesheet href="../../mlarc.xsl" type="text/xsl"?>


<message 
  url="2003/07/bb08176385e0e3626d7033d67ea11fa8"
  from="Xavier Leroy &lt;xavier.leroy@i...&gt;"
  author="Xavier Leroy"
  date="2003-07-06T10:35:48"
  subject="Re: [Caml-list] Printf and format"
  prev="2003/07/dcc51ef8d1c6e45c40c7ae94ca217a7e"
  next="2003/07/a271f4688bedcc68d89571a4f7b2cc1f"
  prev-in-thread="2003/07/1ebeeeaf30083f23aab24519296fd54e"
  prev-thread="2003/07/0dc9c6a5ce74286444025417ac016873"
  next-thread="2003/07/f9cdfa31c48eb391a5653d4f59968d67"
  root="../../"
  period="month"
  listname="caml-list"
  title="Archives of the Caml mailing list">

<thread subject="[Caml-list] Printf and format">
<msg 
  url="2003/07/6a59432f708b13ca5d40751041049c7a"
  from="Sylvain LE GALL &lt;sylvain.le-gall@p...&gt;"
  author="Sylvain LE GALL"
  date="2003-07-03T16:38:11"
  subject="[Caml-list] Printf and format">
<msg 
  url="2003/07/47c86cd9157db833717298b5eff903e4"
  from="Pierre Weis &lt;pierre.weis@i...&gt;"
  author="Pierre Weis"
  date="2003-07-05T10:26:52"
  subject="Re: [Caml-list] Printf and format">
<msg 
  url="2003/07/1ebeeeaf30083f23aab24519296fd54e"
  from="Sylvain LE GALL &lt;sylvain.le-gall@p...&gt;"
  author="Sylvain LE GALL"
  date="2003-07-05T12:07:01"
  subject="Re: [Caml-list] Printf and format">
<msg 
  url="2003/07/bb08176385e0e3626d7033d67ea11fa8"
  from="Xavier Leroy &lt;xavier.leroy@i...&gt;"
  author="Xavier Leroy"
  date="2003-07-06T10:35:48"
  subject="Re: [Caml-list] Printf and format">
</msg>
</msg>
</msg>
</msg>
</thread>

<contents>
&gt; Is there a way to transform string to ( 'a, out_channel, unit, unit)
&gt; format. I need this function to use it with something like :
&gt; 
&gt; Printf.printf (my_fun "X, Y") "coucou";;

No, not in a type-safe manner.  The type of a format string depends on
the "%" specifiers found in the string itself, and OCaml can't infer
or check types at run-time.

However, for the purpose of internationalization, the following
operation suffices: given a (compile-time constant) format and a
(dynamically computed) string, check that the string can be viewed as
a format with the same format type as the constant format, and return
the string as a format.  

In OCaml 3.06, this can be done as follows:

  let re_fmt =
    Str.regexp "%[#0-9.*+ -]*[lnL]?[sScCdioxXunfeEgGFbBatn[]"

  let string_of_format (s : ('a, 'b, 'c) format) = (Obj.magic s : string)

  let extract_formats s =
    List.fold_right
      (fun part accu -&gt;
        match part with Str.Text _ -&gt; accu | Str.Delim d -&gt; d :: accu)
      (Str.full_split re_fmt s) []

  let conv_format (src: ('a, 'b, 'c) format) (dst: string) =
    if extract_formats (string_of_format src) = extract_formats dst
    then (Obj.magic dst : ('a, 'b, 'c) format)
    else failwith "conv_format"

Remark 1: yes, there's a lot of "Obj.magic" in this code, and yes,
this is a deadly sin, but in this particular instance it is all
type-safe nonetheless.

Remark 2: the matching of the two formats can be relaxed, e.g.
the code above will not allow the conversion of "%6d" into "%8x",
although both formats have the same type.  This is left as an exercise
for the reader.  But for internationalization purposes, I doubt
you need that additional flexibility.

Then, assuming you have a function "gettext : string -&gt; string" to translate
strings according to the user-selected language, you can extend it to
formats as follows:

  let getformat f = conv_format f (gettext (string_of_format f))

and use it with printf functions like this:

  printf (getformat "My name is %s and I'm %d years old") "Bob" 12

&gt; you read my mind. Indeed, the question concern an internationalization
&gt; module ( let's call libgettext-ocaml ). It is basically a binding of
&gt; gettext. 

I hope the above is enough to get you off the ground.

- Xavier Leroy

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners

</contents>

</message>

