caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* toplevel with pre-installed printers
@ 2006-01-19 16:28 Andrej Bauer
  2006-01-19 16:53 ` [Caml-list] " Daniel Bünzli
                   ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Andrej Bauer @ 2006-01-19 16:28 UTC (permalink / raw)
  To: Caml list

This seems like a trivial question, but I do not know the answer:
how do I create either a toplevel (or a shell script which appears to be
a toplevel) with pre-installed pretty-printers (and pre-opened modules,
for that matter)?

Andrej


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Caml-list] toplevel with pre-installed printers
  2006-01-19 16:28 toplevel with pre-installed printers Andrej Bauer
@ 2006-01-19 16:53 ` Daniel Bünzli
  2006-01-19 16:57 ` Eric Stokes
  2006-01-20  8:29 ` [Caml-list] " Jean-Christophe Filliatre
  2 siblings, 0 replies; 16+ messages in thread
From: Daniel Bünzli @ 2006-01-19 16:53 UTC (permalink / raw)
  To: Andrej.Bauer; +Cc: Caml list

The toplevel tries to read toplevel phrases from an .ocamlinit file  
present in the current directoy or, if not, from $HOME/.ocamlinit.  
Read there [1], under Unix.

Best,

Daniel

[1] <http://caml.inria.fr/pub/docs/manual-ocaml/manual023.html>


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Caml-list] toplevel with pre-installed printers
  2006-01-19 16:28 toplevel with pre-installed printers Andrej Bauer
  2006-01-19 16:53 ` [Caml-list] " Daniel Bünzli
@ 2006-01-19 16:57 ` Eric Stokes
  2006-01-19 17:08   ` Andrej Bauer
  2006-01-20  8:29 ` [Caml-list] " Jean-Christophe Filliatre
  2 siblings, 1 reply; 16+ messages in thread
From: Eric Stokes @ 2006-01-19 16:57 UTC (permalink / raw)
  To: Andrej.Bauer; +Cc: Caml list

When the toplevel starts up, it evaluates (on unix) ~/.ocamlinit,  
which can contain arbitrary ocaml expressions.

On Jan 19, 2006, at 8:28 AM, Andrej Bauer wrote:

> This seems like a trivial question, but I do not know the answer:
> how do I create either a toplevel (or a shell script which appears  
> to be
> a toplevel) with pre-installed pretty-printers (and pre-opened  
> modules,
> for that matter)?
>
> Andrej
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Caml-list] toplevel with pre-installed printers
  2006-01-19 16:57 ` Eric Stokes
@ 2006-01-19 17:08   ` Andrej Bauer
  2006-01-19 17:49     ` Richard Jones
  2006-01-20 14:13     ` code17
  0 siblings, 2 replies; 16+ messages in thread
From: Andrej Bauer @ 2006-01-19 17:08 UTC (permalink / raw)
  To: Eric Stokes; +Cc: Caml list

Eric Stokes wrote:
> When the toplevel starts up, it evaluates (on unix) ~/.ocamlinit,  
> which can contain arbitrary ocaml expressions.

Sorry, I was not clear enough. I know about .ocamlinit. I am going to
have several custom ocamltop's and they can't all share the same
.ocamlinit. What now?

Andrej

P.S. Ocaml toplevel could use a bit of improvements.


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Caml-list] toplevel with pre-installed printers
  2006-01-19 17:08   ` Andrej Bauer
@ 2006-01-19 17:49     ` Richard Jones
  2006-01-19 19:12       ` Eric Cooper
  2006-01-20 14:13     ` code17
  1 sibling, 1 reply; 16+ messages in thread
From: Richard Jones @ 2006-01-19 17:49 UTC (permalink / raw)
  To: Andrej Bauer; +Cc: Eric Stokes, Caml list

On Thu, Jan 19, 2006 at 06:08:06PM +0100, Andrej Bauer wrote:
> Eric Stokes wrote:
> > When the toplevel starts up, it evaluates (on unix) ~/.ocamlinit,  
> > which can contain arbitrary ocaml expressions.
> 
> Sorry, I was not clear enough. I know about .ocamlinit. I am going to
> have several custom ocamltop's and they can't all share the same
> .ocamlinit. What now?

We tried to do the same thing and couldn't find a way.  One rather
nasty suggestion involved a surrounding shell script which would
launch the right toplevel in the right directory with the right
.ocamlinit.  It's not pleasant.

Rich.

-- 
Richard Jones, CTO Merjis Ltd.
Merjis - web marketing and technology - http://merjis.com
Team Notepad - intranets and extranets for business - http://team-notepad.com


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Caml-list] toplevel with pre-installed printers
  2006-01-19 17:49     ` Richard Jones
@ 2006-01-19 19:12       ` Eric Cooper
  2006-01-19 20:18         ` Richard Jones
  0 siblings, 1 reply; 16+ messages in thread
From: Eric Cooper @ 2006-01-19 19:12 UTC (permalink / raw)
  To: caml-list, Caml list

On Thu, Jan 19, 2006 at 05:49:07PM +0000, Richard Jones wrote:
> On Thu, Jan 19, 2006 at 06:08:06PM +0100, Andrej Bauer wrote:
> > Eric Stokes wrote:
> > > When the toplevel starts up, it evaluates (on unix) ~/.ocamlinit,  
> > > which can contain arbitrary ocaml expressions.
> > 
> > Sorry, I was not clear enough. I know about .ocamlinit. I am going to
> > have several custom ocamltop's and they can't all share the same
> > .ocamlinit. What now?
> 
> We tried to do the same thing and couldn't find a way.  One rather
> nasty suggestion involved a surrounding shell script which would
> launch the right toplevel in the right directory with the right
> .ocamlinit.  It's not pleasant.

In a single "master" .ocamlinit, you could dispatch on
Sys.executable_name, and perhaps Sys.getcwd.  Still a hack, but it
might avoid (non-OCaml) wrapper scripts.

-- 
Eric Cooper             e c c @ c m u . e d u


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Caml-list] toplevel with pre-installed printers
  2006-01-19 19:12       ` Eric Cooper
@ 2006-01-19 20:18         ` Richard Jones
  2006-01-20  2:24           ` skaller
  0 siblings, 1 reply; 16+ messages in thread
From: Richard Jones @ 2006-01-19 20:18 UTC (permalink / raw)
  To: caml-list

On Thu, Jan 19, 2006 at 02:12:59PM -0500, Eric Cooper wrote:
> In a single "master" .ocamlinit, you could dispatch on
> Sys.executable_name, and perhaps Sys.getcwd.  Still a hack, but it
> might avoid (non-OCaml) wrapper scripts.

This is a clever idea.  However one of the other problems is that
people could run the toplevel from another directory.  This is
particularly important in the case where we install the toplevel as a
binary in, say, /usr/bin.

Rich.

-- 
Richard Jones, CTO Merjis Ltd.
Merjis - web marketing and technology - http://merjis.com
Team Notepad - intranets and extranets for business - http://team-notepad.com


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Caml-list] toplevel with pre-installed printers
  2006-01-19 20:18         ` Richard Jones
@ 2006-01-20  2:24           ` skaller
  2006-01-20 16:49             ` David Brown
  0 siblings, 1 reply; 16+ messages in thread
From: skaller @ 2006-01-20  2:24 UTC (permalink / raw)
  To: Richard Jones; +Cc: caml-list

On Thu, 2006-01-19 at 20:18 +0000, Richard Jones wrote:
> On Thu, Jan 19, 2006 at 02:12:59PM -0500, Eric Cooper wrote:
> > In a single "master" .ocamlinit, you could dispatch on
> > Sys.executable_name, and perhaps Sys.getcwd.  Still a hack, but it
> > might avoid (non-OCaml) wrapper scripts.
> 
> This is a clever idea. 

It's an old one too. gcc does it. The problem is portability.

You simply look at argv[0] which on some Unix systems
is the full path name of the invoked executable.

In particular, its the path name of the symlink to the
executable, not the binary. Thus, you can find the
directory containing the symlink, and thus the resources
associated with that particular symlink.

All you need is a unique symlink for every context,
and a fixed way of finding files relative to the
location of the symlink.

The problem is that there is no guarantee argv[0] is
in fact the full pathname of the symlink on all Unix
systems .. it works on Linux though.

The two other techniques commonly used to solve this problem are

(a) a wrapper script passing a command line argument
(b) an environment variable

./ocamlinit script can certainly read an environment variable.
It can also read the command line arguments .. so all you
really need is to ask for a patch to the toplevel which
allows you to pass it an argument it totally ignores!


-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Caml-list] toplevel with pre-installed printers
  2006-01-19 16:28 toplevel with pre-installed printers Andrej Bauer
  2006-01-19 16:53 ` [Caml-list] " Daniel Bünzli
  2006-01-19 16:57 ` Eric Stokes
@ 2006-01-20  8:29 ` Jean-Christophe Filliatre
  2006-01-20 13:13   ` Gerd Stolpmann
  2 siblings, 1 reply; 16+ messages in thread
From: Jean-Christophe Filliatre @ 2006-01-20  8:29 UTC (permalink / raw)
  To: Andrej.Bauer; +Cc: Caml list


Hello,

Andrej Bauer writes:
 > This seems like a trivial question, but I do not know the answer:
 > how do I create either a toplevel (or a shell script which appears to be
 > a toplevel) with pre-installed pretty-printers (and pre-opened modules,
 > for that matter)?

I learnt a trick to do that from David Monniaux's GMP interface.

First define  your pretty-printers using the Ocaml  module Format. For
instance, the GMP pretty-printers look like

== gmp_pp.ml =========================================================
open Gmp
open Format
let z z = print_string (Z.string_from z)
let q q = ...
======================================================================

then introduce another file installing the pretty-printers:

== install_gmp_pp.ml =================================================
(* This is a hack to install the pretty-printers in the customized toplevel. *)

(* Caml longidents. *)
type t =
  | Lident of string
  | Ldot of t * string
  | Lapply of t * t

let _ = Topdirs.dir_directory "+creal"

let _ = Topdirs.dir_install_printer Format.std_formatter 
	  (Obj.magic (Ldot (Lident "Gmp_pp", "z")) : 'a)

let _ = Topdirs.dir_install_printer Format.std_formatter 
	  (Obj.magic (Ldot (Lident "Gmp_pp", "q")) : 'a)
======================================================================

Finally,  build your  ocaml toplevel  the usual  way, linking  the two
files above:

======================================================================
ocamlgmp: gmp.cma gmp_pp.cmo install_gmp_pp.cmo
	ocamlmktop -custom -o $@ $^
======================================================================

I know  this is a  hack (the infamous  Obj.magic is used and  the Caml
longident  type could change  in a  next ocaml  version) but  it works
fine.

Hope this helps,
-- 
Jean-Christophe Filliâtre (http://www.lri.fr/~filliatr)


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Caml-list] toplevel with pre-installed printers
  2006-01-20  8:29 ` [Caml-list] " Jean-Christophe Filliatre
@ 2006-01-20 13:13   ` Gerd Stolpmann
  0 siblings, 0 replies; 16+ messages in thread
From: Gerd Stolpmann @ 2006-01-20 13:13 UTC (permalink / raw)
  To: Jean-Christophe Filliatre; +Cc: Andrej.Bauer, Caml list

Am Freitag, den 20.01.2006, 09:29 +0100 schrieb Jean-Christophe
Filliatre:
> First define  your pretty-printers using the Ocaml  module Format. For
> instance, the GMP pretty-printers look like

In Ocamlnet, we use a similar trick, but get around Obj.magic:

let exec s =
  let l = Lexing.from_string s in
  let ph = !Toploop.parse_toplevel_phrase l in
  assert(Toploop.execute_phrase false Format.err_formatter ph)
;;

exec "#install_printer Mimestring.print_s_param;;";;
exec "#install_printer Neturl.print_url;;";;
exec "#install_printer Netbuffer.print_buffer;;";;
exec "#install_printer Netstream.print_in_obj_stream;;";;

This module can be simply compiled to bytecode and can be loaded into
the toplevel. As we are using findlib, a second trick automates this. In
META we have

archive(byte,toploop) =
    "netstring.cma netstring_top.cmo"

where netstring.cma contains the generic code and netstring_top.cma the
toplevel-specific code. So when the user types #require "netstring" the
toplevel printers are automatically available.

Gerd


> 
> == gmp_pp.ml =========================================================
> open Gmp
> open Format
> let z z = print_string (Z.string_from z)
> let q q = ...
> ======================================================================
> 
> then introduce another file installing the pretty-printers:
> 
> == install_gmp_pp.ml =================================================
> (* This is a hack to install the pretty-printers in the customized toplevel. *)
> 
> (* Caml longidents. *)
> type t =
>   | Lident of string
>   | Ldot of t * string
>   | Lapply of t * t
> 
> let _ = Topdirs.dir_directory "+creal"
> 
> let _ = Topdirs.dir_install_printer Format.std_formatter 
> 	  (Obj.magic (Ldot (Lident "Gmp_pp", "z")) : 'a)
> 
> let _ = Topdirs.dir_install_printer Format.std_formatter 
> 	  (Obj.magic (Ldot (Lident "Gmp_pp", "q")) : 'a)
> ======================================================================
> 
> Finally,  build your  ocaml toplevel  the usual  way, linking  the two
> files above:
> 
> ======================================================================
> ocamlgmp: gmp.cma gmp_pp.cmo install_gmp_pp.cmo
> 	ocamlmktop -custom -o $@ $^
> ======================================================================
> 
> I know  this is a  hack (the infamous  Obj.magic is used and  the Caml
> longident  type could change  in a  next ocaml  version) but  it works
> fine.
> 
> Hope this helps,
-- 
------------------------------------------------------------
Gerd Stolpmann * Viktoriastr. 45 * 64293 Darmstadt * Germany 
gerd@gerd-stolpmann.de          http://www.gerd-stolpmann.de
Telefon: 06151/153855                  Telefax: 06151/997714
------------------------------------------------------------


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: toplevel with pre-installed printers
  2006-01-19 17:08   ` Andrej Bauer
  2006-01-19 17:49     ` Richard Jones
@ 2006-01-20 14:13     ` code17
  1 sibling, 0 replies; 16+ messages in thread
From: code17 @ 2006-01-20 14:13 UTC (permalink / raw)
  To: caml-list


Andrej Bauer <Andrej.Bauer@andrej.com> writes:
> Sorry, I was not clear enough. I know about .ocamlinit. I am going to
> have several custom ocamltop's and they can't all share the same
> .ocamlinit. What now?

I recently worked on a problem about customized toplevel. I need a
generic toplevel with various kinds of preloaded modules and open them
beforehand. So I can't produce these toplevels statically using
ocamlmktop, I have to launch them with various configurations on the
fly. Maybe this is also your situation. Here are some results I've got
(especially from the beginner's list, hi Richard Jones :-)

Case 1:
  Suppose your requirement is quite simple: pre-load variant modules,
  open them, execute some evaluations and primitives without showing the
  feedback ... and you don't have to do complex interpretation between
  the user input as well as feedback from the real ocaml toplevel.

  You would probably like to use the undocumented(why?) option "-init",
  then wrap your executable as a shell script or programs. Use it like the
  default .ocamlinit except now you can indicate who is the script for
  initialization. E.g.
  
  <code>
  tmp/init.ml:

  # load "bigarray.cma";;
  open Bigarray.Genarray;;
  (* You may even delete it after execution, maybe dangerous *)
  Sys.command "rm tmp/init.ml";;
  </code>

  <command>
  ocaml -init tmp/init.ml
  </command>

  <toplevel>
            Objective Caml version 3.09.0

  # create;;
  - : ('a, 'b) Bigarray.kind ->
      'c Bigarray.layout -> int array -> ('a, 'b, 'c) Bigarray.Genarray.t
  = <fun>
  # 
  </toplevel>

  Obviously you can have different configuration for different toplevels
  you want, and even produce the configuration on the fly.

Case 2:
  If you want to do complex interpretation between your user and the
  real ocaml toplevel, e.g. you want "My own topleve" instead of
  "Objective Caml version 3.09" showing at the beginning, you want to
  interpret the user's input secretly before feeding them to the
  toplevel (maybe camlp4 help to do anything possible here?) and hide or
  modify feedback from ocaml (maybe personalized pretty printer can
  solve any problem here?). 

  Either you are quite familiar with toplevel source and hack by
  yourself, or like me really provide a program acting as translator,
  i.e. another process active between user and the background running
  toplevel. Then you can do anything as you want. I've done so, and wish
  to provide some of the generic functionality as library when I've got
  time to clean my code.

Wish it helps!


code17




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Caml-list] toplevel with pre-installed printers
  2006-01-20  2:24           ` skaller
@ 2006-01-20 16:49             ` David Brown
  2006-01-20 19:29               ` skaller
  0 siblings, 1 reply; 16+ messages in thread
From: David Brown @ 2006-01-20 16:49 UTC (permalink / raw)
  To: skaller; +Cc: Richard Jones, caml-list

On Fri, Jan 20, 2006 at 01:24:03PM +1100, skaller wrote:

> You simply look at argv[0] which on some Unix systems
> is the full path name of the invoked executable.

Actually, argv[0] is almost never a full path.  It is the path used to
invoke the executable.  So, if the program is in the user's path, then it
will just be the filename, with no path information.

In order to find itself, a program has to search for argv[0] in $PATH.

If you don't believe me, try it:

hello.c:
   #include <stdio.h>
   
   int
   main (int argc, char **argv)
   {
     printf ("Program name: %s\n", argv[0]);
   }

% gcc -o ~/bin/hello hello.c
% hello
Program name: hello

Dave


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Caml-list] toplevel with pre-installed printers
  2006-01-20 16:49             ` David Brown
@ 2006-01-20 19:29               ` skaller
  0 siblings, 0 replies; 16+ messages in thread
From: skaller @ 2006-01-20 19:29 UTC (permalink / raw)
  To: David Brown; +Cc: caml-list, Richard Jones

On Fri, 2006-01-20 at 08:49 -0800, David Brown wrote:
> On Fri, Jan 20, 2006 at 01:24:03PM +1100, skaller wrote:
> 
> > You simply look at argv[0] which on some Unix systems
> > is the full path name of the invoked executable.
> 
> Actually, argv[0] is almost never a full path. 

You're right. Hmm .. but your example is complicated,
here's a simpler version:

skaller@rosella:/work/felix/flx$ echo $0
bash

.. clearly not the full path.

-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


^ permalink raw reply	[flat|nested] 16+ messages in thread

* RE: [Caml-list] toplevel with pre-installed printers
@ 2006-01-20 20:19 Harrison, John R
  0 siblings, 0 replies; 16+ messages in thread
From: Harrison, John R @ 2006-01-20 20:19 UTC (permalink / raw)
  To: skaller; +Cc: Caml list

| Under "Linux" ckpt is not available. I tried this, since HOL Light
takes
| ages to load. I even tried to build ckpt from source with no luck.
| Maybe it works for x86 .. but I'm running an x86_64.

I wasn't aware of that problem. It works fine on 32-bit x86, though
there
are some peculiarities of certain Linux variants. I'll look into this,
since I suppose I'll want it myself one day.

| Is there some reason HOL Light doesn't load bytecode?

It's not so much the code (of automated proof procedures etc.) that
slows
the load down, but actually running the proofs to arrive at the basic
core of theorems. Loading as bytecode won't help that significantly.

It would be possible to restructure the code to completely separate data
(theorems) from code (proof procedures), load the former via marshalling
and the latter as bytecode. But it's not very natural to do so, since
one
often wants to introduce theorems and proof procedures in a tightly
interleaved manner.

John.


^ permalink raw reply	[flat|nested] 16+ messages in thread

* RE: [Caml-list] toplevel with pre-installed printers
  2006-01-19 19:40 Harrison, John R
@ 2006-01-20  1:30 ` skaller
  0 siblings, 0 replies; 16+ messages in thread
From: skaller @ 2006-01-20  1:30 UTC (permalink / raw)
  To: Harrison, John R; +Cc: Andrej.Bauer, Caml list

On Thu, 2006-01-19 at 11:40 -0800, Harrison, John R wrote:
> | Sorry, I was not clear enough. I know about .ocamlinit. I am going to
> | have several custom ocamltop's and they can't all share the same
> | .ocamlinit. What now?
> 
> You could always checkpoint the OCaml toplevel process. This is what
> I do with HOL Light, since it would take several minutes to reload all
> the code at startup. Under Linux, I've found "ckpt" very good. However
> I don't know of a comparable solution for Windows.

Under "Linux" ckpt is not available. I tried this, since HOL Light takes
ages to load. I even tried to build ckpt from source with no luck.
Maybe it works for x86 .. but I'm running an x86_64.
Is there some reason HOL Light doesn't load bytecode?

-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


^ permalink raw reply	[flat|nested] 16+ messages in thread

* RE: [Caml-list] toplevel with pre-installed printers
@ 2006-01-19 19:40 Harrison, John R
  2006-01-20  1:30 ` skaller
  0 siblings, 1 reply; 16+ messages in thread
From: Harrison, John R @ 2006-01-19 19:40 UTC (permalink / raw)
  To: Andrej.Bauer; +Cc: Caml list

| Sorry, I was not clear enough. I know about .ocamlinit. I am going to
| have several custom ocamltop's and they can't all share the same
| .ocamlinit. What now?

You could always checkpoint the OCaml toplevel process. This is what
I do with HOL Light, since it would take several minutes to reload all
the code at startup. Under Linux, I've found "ckpt" very good. However
I don't know of a comparable solution for Windows.

John.


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2006-01-20 20:19 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-01-19 16:28 toplevel with pre-installed printers Andrej Bauer
2006-01-19 16:53 ` [Caml-list] " Daniel Bünzli
2006-01-19 16:57 ` Eric Stokes
2006-01-19 17:08   ` Andrej Bauer
2006-01-19 17:49     ` Richard Jones
2006-01-19 19:12       ` Eric Cooper
2006-01-19 20:18         ` Richard Jones
2006-01-20  2:24           ` skaller
2006-01-20 16:49             ` David Brown
2006-01-20 19:29               ` skaller
2006-01-20 14:13     ` code17
2006-01-20  8:29 ` [Caml-list] " Jean-Christophe Filliatre
2006-01-20 13:13   ` Gerd Stolpmann
2006-01-19 19:40 Harrison, John R
2006-01-20  1:30 ` skaller
2006-01-20 20:19 Harrison, John R

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).