From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=AWL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by yquem.inria.fr (Postfix) with ESMTP id 791DABC6B for ; Sat, 10 Nov 2007 20:22:28 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgoXAG+TNUfUnw7XYmdsb2JhbACCOYw/FQQGEBk X-IronPort-AV: E=Sophos;i="4.21,399,1188770400"; d="scan'208";a="5657879" Received: from fhw-relay07.plus.net ([212.159.14.215]) by mail3-smtp-sop.national.inria.fr with ESMTP; 10 Nov 2007 20:22:27 +0100 Received: from [80.229.56.224] (helo=beast.local) by fhw-relay07.plus.net with esmtp (Exim) id 1IqvuV-0003Qv-DK for caml-list@yquem.inria.fr; Sat, 10 Nov 2007 19:22:27 +0000 From: Jon Harrop Organization: Flying Frog Consultancy Ltd. To: caml-list@yquem.inria.fr Subject: Re: [Caml-list] OCaml's formatting libraries Date: Sat, 10 Nov 2007 19:13:14 +0000 User-Agent: KMail/1.9.5 References: <9d3ec8300711080617g1b023711o1a8f9aa50b7874@mail.gmail.com> <200711101458.04047.jon@ffconsultancy.com> In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Message-Id: <200711101913.14541.jon@ffconsultancy.com> X-Spam: no; 0.00; ocaml's:01 bunzli:01 unparsing:01 printf:01 foo:01 flt:01 foo:01 ocaml:01 trivial:01 flt:01 val:01 printf:01 knuth:01 ocaml's:01 ocaml:01 On Saturday 10 November 2007 15:43, B=FCnzli Daniel wrote: > Le 10 nov. 07 =E0 15:58, Jon Harrop a =E9crit : > > Functional unparsing requires a lot more code, > > It's a little bit less concise but I wouldn't say it is a *lot*. printf "%25s %d\n%25s %g\n%25s %s\n\n%25s ]%*d[\n%25s ]%*d[\n\ %25s ]%*g[\n%25s ]%*g[\n%25s ]%*s[\n%25s ]%*s[\n" "int:" 10 "float:" 1.234 "string:" "foo" "int with width:" 20 24 "int with -width:" (-20) 42 "float with width:" 20 1.234 "float with -width:" (-20) 567.8 "string with width:" 20 "Hello" "string with -width:" (-20) "Goodbye" vs: print_string (format (wlit "int:" 25 $ lit " " $ int $ nl $ wlit "float:" 25 $ lit " " $ flt $ nl $ wlit "string:" 25 $ lit " " $ str $ nnl 2 $ wlit "int with width:" 25 $ lit " ]" $ intw $ lit "[" $ nl $ wlit "int with -width:" 25 $ lit " ]" $ intw $ lit "[" $ nl $ wlit "float with width:" 25 $ lit " ]" $ fltw $ lit "[" $ nl $ wlit "float with -width:" 25 $ lit " ]" $ fltw $ lit "[" $ nl $ wlit "string with width:" 25 $ lit " ]" $ strw $ lit "[" $ nl $ wlit "string with -width:" 25 $ lit " ]" $ strw $ lit "[" $ nl ) () 10 1.234 "foo" (* int, float, string *) 24 20 42 (-20) (* int with width, -width spec *) 1.234 20 567.8 (-20) (* float with width, -width spec *) "Hello" 20 (* string with width spec *) "Goodbye" (-20) (* string with -width spec *) ) > > produces worse error messages, > > Example please. Oops, I forgot one of the 36 superfluous "$" operators. OCaml now fails to= =20 catch my trivial (but likely) mistake and now my program produces incorrect= =20 output and the patient dies on the table whilst gurgling out "should've spe= nt=20 less time proving correctness and more time testing": # let test1 () =3D print_string (format (wlit "int:" 25 $ lit " " $ int $ nl = $ wlit "float:" 25 $ lit " " $ flt $ nl = $ wlit "string:" 25 $ lit " " $ str $ nnl = 2 $ wlit "int with width:" 25 $ lit " ]" $ intw $ lit "[" $ nl wlit "int with -width:" 25 $ lit " ]" $ intw $ lit "[" $ nl = $ wlit "float with width:" 25 $ lit " ]" $ fltw $ lit "[" $ nl = $ wlit "float with -width:" 25 $ lit " ]" $ fltw $ lit "[" $ nl = $ wlit "string with width:" 25 $ lit " ]" $ strw $ lit "[" $ nl = $ wlit "string with -width:" 25 $ lit " ]" $ strw $ lit "[" $ nl = ) () 10 1.234 "foo" (* int, float, string *) 24 20 42 (-20) (* int with width, -width spec *) 1.234 20 567.8 (-20) (* float with width, -width spec = *) "Hello" 20 (* string with width spec *) "Goodbye" (-20) (* string with -width spec *) );; val test1 : unit -> unit =3D # test1();; int: 10 float: 1.234 string: foo int with width: ] 24[ int with -width: ]42 [ float with width: ] 1.234[ float with -width: ]567.8 [ string with width: ] Hello[ string with -width: ]Goodbye [ =2D : unit =3D () > > is much harder to learn, > > I don't think so. There really nothing hard in it, it is just ... > different. Exactly: how many people have heard of printf and how many have heard of=20 continuation passing style, let alone functional unparsers? > > is incompatible with the excellent Format module, > > Which wouldn't prevent the design of a new format module. Sure. But we're an extremely finite-sized community and need to prioritize= =20 where we put our efforts. My vote simply goes to putting effort elsewhere. > > I'd much rather see effort put into visualization and GUI tools > > rather than > > ASCII text tools... > > I'd rather have a simple and correct type system. I'd rather have feature-complete software that works. In practice, a language implementation will only become robust if it has bo= th=20 a solid theoretical foundation and a significant user base to test the=20 implementation. As Knuth said "beware: I have proven it correct but not=20 tested it". With the benefit of hindsight, Standard ML put too much emphasis on=20 theoretical correctness and not enough on practical utility. Consequently,= =20 Standard ML does not enjoy OCaml's popularity, has fewer libraries, no=20 competitively performant compilers and so on. I would not like to see OCaml= =20 take that route. In this context, I would have thought that printf is very commonly used but= =20 scanf is not. If scanf is difficult to fix then these features could simply= =20 be removed from it. =2D-=20 Dr Jon D Harrop, Flying Frog Consultancy Ltd. http://www.ffconsultancy.com/products/?e