From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from majordomo@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id UAA13844; Mon, 29 Sep 2003 20:57:48 +0200 (MET DST) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id UAA12074 for ; Mon, 29 Sep 2003 20:57:47 +0200 (MET DST) Received: from mail.messagingengine.com (out1.smtp.messagingengine.com [66.111.4.25]) by nez-perce.inria.fr (8.11.1/8.11.1) with ESMTP id h8TIvj515585 for ; Mon, 29 Sep 2003 20:57:45 +0200 (MET DST) Received: from mail.messagingengine.com (localhost [127.0.0.1]) by localhost.localdomain (Postfix) with ESMTP id 3B47923EBF8 for ; Mon, 29 Sep 2003 14:57:43 -0400 (EDT) Received: from 10.202.2.150 ([10.202.2.150] helo=mail.messagingengine.com) by messagingengine.com with SMTP; Mon, 29 Sep 2003 14:57:43 -0400 X-Epoch: 1064861863 X-Sasl-enc: 1DDLdPAujCgARks7rRQh0Q Received: from [192.168.0.135] (f07v-10-82.d1.club-internet.fr [212.194.141.82]) by mail.messagingengine.com (Postfix) with ESMTP id 1A81723EC22 for ; Mon, 29 Sep 2003 14:57:42 -0400 (EDT) Date: Mon, 29 Sep 2003 20:57:36 +0200 (CEST) From: Martin Jambon X-X-Sender: martin@pc-bioinfo1 To: caml-list@inria.fr Subject: Re: [Caml-list] Printing text with holes In-Reply-To: <3F786FC3.4020807@lexifi.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Loop: caml-list@inria.fr X-Spam: no; 0.00; caml-list:01 stdout:01 printf:01 printf:01 ocaml's:01 recursively:01 pretty-print:01 -dimensional:01 specifier:01 ranking:99 vol:99 vol:99 ranking:99 expressing:01 arrays:01 Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk On Mon, 29 Sep 2003, Jean-Marc EBER wrote: > > > > This would allow you to do: > > let _ = stdout <$ "Hello " <$ first_name <$ " " <$ last_name <$ "! It is " > > <$ (string_of_int time) <$ " o'clock.\n";; > > > > Not quite as clean, but close, and it doesn't require p4. > > > > With "old" printf approach, you write something like: > let _ = > printf "Hello %s %s! It is %i o'clock.\n" first_name last_name time > > Matter of taste: I prefer the printf version. > > More generally, I have found the printf approach (more precisely OCaml's > Format 'magic' standard module) of incredible power and flexibility, if > (and only if :-) ) used consistently through *all* your program. This > is especially true when you generate "big" documents, where you compose > recursively many "nice" ways to pretty-print your result(s). Yes, printf is OK if you don't have to do many substitutions in one time. This is probably the case most of the time for printing structured output. But printing human-readable text has a strong constraint: it must fit on one 2-dimensional page, with a nice appearance and few empty parts. This is why the programmer likes to have an overview of the output. Having an overview of the output (its shape) is totally useless if you need to print tree-like data to be read by a machine. Just imagine that we want to use a kind of LaTeX or HTML formatting style from Caml, or find some better solution :-) In our situation, the problem is that the efforts required for a modification (let's say the insertion of a new variable) grow with the size of the output. This is even harder when all your variables have the same type and if there is more than one screen between the format specifier and the variable. Well, I just extracted some code from one of my CGI programs. Here, the purpose is to print one line of an HTML table, where one column should appear in bold face (using arrays containing strings "" or "" or ""). Here is the code: let print_binary_patch id bb be ranking p = let volume1 = p.patch_1.volume in let volume2 = p.patch_2.volume in let vol_percentage1 = p.patch_1.relative_volume *. 100. in let vol_percentage2 = p.patch_2.relative_volume *. 100. in let print_option = function None -> () | Some s -> << ($s) >> in << $int{ranking} $matched_tags{p} [View] [Quick view] ${bb.(1)}$g{p.patch_global.patch_size}${be.(1)} ${bb.(2)}$r1{vol_percentage1}% ($r1{volume1})${be.(2)} ${bb.(3)}$r2{vol_percentage2}% ($r2{volume2})${be.(3)} ${bb.(4)}$int{p.patch_1.pdb_group_number}${be.(4)} ${bb.(5)}$int{p.patch_2.pdb_group_number}${be.(5)} ${bb.(6)}$f3{p.patch_global.patch_sumo_score}${be.(6)} >> This does not look very beautiful, but for me it is important to have a compact representation where one line of source code produces not less than one line of output. This allows to have a global overview of the output without having to run the program. The above piece of code has 28 holes... that we must be able to modify at any time, just because we don't print all the data. I would like to thank everyone for expressing their opinion on the subject! -- Martin ------------------- 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