caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Markus Mottl <markus.mottl@gmail.com>
To: OCaml <caml-list@inria.fr>
Subject: Installing pretty-printers automagically
Date: Wed, 23 Mar 2005 13:58:18 -0500	[thread overview]
Message-ID: <f8560b80503231058229e505e@mail.gmail.com> (raw)

Hi,

though the idea is not new, more precisely, I have shamelessly stolen
it from Gerd Stolpmann's findlib sources, it still seems not widespread
and is such a useful thing to have that it should be mentioned here on
the list.

You will quite often want to have custom pretty-printers for your
datatypes in the toplevel.  Preferably, they should be installed as
soon as the library implementing them has been loaded.

The solution for this is quite simple, and I have just implemented it
in the LACAML-library so that matrices and vectors can be printed in
the toplevel.

Assuming you have already implemented a pretty-printer with the correct
signature in module "My_module":

  val pp_my_type : Format.formatter -> my_type -> unit

Then just create another module in your library:                                
---------------------------------------------------------------------------
let printers =
  [
    "My_module.pp_my_type";
  ]

let eval_string
      ?(print_outcome = false) ?(err_formatter = Format.err_formatter) str =
  let lexbuf = Lexing.from_string str in
  let phrase = !Toploop.parse_toplevel_phrase lexbuf in
  Toploop.execute_phrase print_outcome err_formatter phrase

let rec install_printers = function
  | [] -> true
  | printer :: printers ->
      let cmd = Printf.sprintf "#install_printer %s;;" printer in
      eval_string cmd && install_printers printers

let () =
  if not (install_printers printers) then
    Format.eprintf "Problem installing printers@."
---------------------------------------------------------------------------

Just add further pretty-printers to the list "printers" if required.

If you link this module into a byte-code library and load it into the
toplevel (using #load), you will be able to print your types using the 
custom pretty-printers.

There is one caveat here: the resulting library cannot be used for linking
with byte-code executables, because the toplevel is not available there.  
Therefore, if you want to implement a library, you will have to link
two separate ones: one with and one without the module for installing
the printers.

If you happen to use "ocamlfind" to "#require" your libraries, you just
need to add a line to the META-file for each kind of library.  The right
one will be chosen automatically then, e.g.:

  archive(byte)="mylib.cma"
  archive(byte,toploop)="mylib_top.cma"

Here is a short demonstration using the pretty-printers of the
LACAML-library in the toplevel while computing the singular value
decomposition of a 3x3 Hilbert-matrix:

---------------------------------------------------------------------------
# #require "lacaml";;
/usr/local/home/godi/godi/lib/ocaml/std-lib/bigarray.cma: loaded
/usr/local/home/godi/godi/lib/ocaml/site-lib/lacaml: added to search path
/usr/local/home/godi/godi/lib/ocaml/site-lib/lacaml/lacaml_top.cma: loaded
# open Lacaml.D;;
# let mat = Mat.hilbert 3;;
val mat : Lacaml_float64.mat = 
         1      0.5 0.333333
       0.5 0.333333     0.25
  0.333333     0.25      0.2
# gesvd mat;;
- : Lacaml_float64.vec * Lacaml_float64.mat * Lacaml_float64.mat = 
(   1.40832
   0.122327
 0.00268734,
 -0.827045  0.547448  0.127659
 -0.459864  -0.52829 -0.713747
 -0.323298 -0.649007  0.688672,
 -0.827045 -0.459864 -0.323298
  0.547448  -0.52829 -0.649007
  0.127659 -0.713747  0.688672)
---------------------------------------------------------------------------

Enjoy this trick...

Best regards,
Markus

-- 
Markus Mottl        http://www.ocaml.info        markus.mottl@gmail.com


                 reply	other threads:[~2005-03-23 18:58 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=f8560b80503231058229e505e@mail.gmail.com \
    --to=markus.mottl@gmail.com \
    --cc=caml-list@inria.fr \
    /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;
as well as URLs for NNTP newsgroup(s).