views:

342

answers:

6

Hi,

When working in the ocaml or ghci toplevels I often build up a significant "context" for want of a better word, values bound, functions, modules loaded, and so on. Is there a way to save all of that and reload it later so I can continue exactly where I left off? Or better yet, dump out the entire lot as a text file that could be reloaded or be trivially modified into code that I could compile into an executable (e.g. by adding a Main)?

Thanks!

+5  A: 

At least in OCaml there's no built-in support for that. On solution is to use rlwrap or any other readline wrapper to record your input's history to a file. For example :

> rlwrap -H mysession.ml ocaml

The drawback is that this will also record the input that had syntax errors so you'll have to clean that out. Note that by default rlwrap will automatically save your input in ~/.ocaml_history if you invoke it without the -H option.

Daniel Bünzli
I do already have an alias defined in my shell, oc='rlwrap ocaml' so that's easy to do and would get me back to where I was with #use... I guess what I'd like is an equivalent of the shell's "env" command that dumps out all the environment variables.
Gaius
+6  A: 

In Haskell, just use :e file. This opens the standard editor and lets you edit some file. Afterwards, use :r to reload it. It will be automatically recompiled.

Please notice, that all your "ad-hoc" defined functions will be lost after this. Refer to the doc for more information.

FUZxxl
An alternative to that is to work in haskell-mode in Emacs, edit a file and C-c C-l to send it to the inferior process. If that were bi-directional it would be perfect.
Gaius
Run ghci within Emacs, then `:e` from there? Not entirely seriously...
John
+4  A: 

ghci uses haskeline for commandline input history, so you can scroll up to repeat/edit inputs. Your input history is usually recorded in a file, which you can find as ghci_history in the directory given by

System.Directory.getAppUserDataDirectory "ghc"

There are various commands to explore the 'context' (:show bindings, :show modules, :def, ..) but their output won't suffice to reproduce your session (though it is worth knowing about them anyway).

In general, the advice to combine your ghci session with an open editor window is sound: if it is more than a throwaway definition, even if just for debugging purposes, better include it in a module to be loaded into ghci, so that you can reuse it.

Oh, and if by 'context', you mean some default settings or modules you want loaded, on a per-project basis, there is also ghci's configuration file. Also handy for defining your own ghci commands.

claus
+5  A: 

Users of HOL light have had similar needs, and they use a checkpointing program to save a snapshot of the toplevel. See this message on the caml mailing-list, or page 8 of this HOL tutorial.

In general it is better to keep the definitions as source code, rather than a binary toplevel snapshot. Numerous tools allow to quickly load a .ml file into the toplevel for easy experimentation (emacs modes, etc.). See the warning in the HOL tutorial:

When developing large proofs in HOL, you should always keep the proof script as an OCaml file ready to reload, rather than relying on ckpt. This will allow the proofs to be later modified, used by others etc. However, it can be very convenient to make intermediate snapshots so you do not have to load large files to work further on a proof. This is analogous to the usual situation in programming: you should always keep your complete source code, but don’t want to recompile all the sources each time you use the code.

gasche
+4  A: 

In ocaml, you can build your own top-level. It solves problem with loaded modules at least.

http://caml.inria.fr/pub/docs/manual-ocaml/manual023.html#toc93

larhat
I use that technique, I saw a post on the Jane Street blog about building "scripting" toplevels with the most useful/relevant things. But the use case I'm thinking of is along the lines of exploratory/experimental work, that I want to be able to keep to guard against a reboot, or to transfer to another machine and pick up where I left off.
Gaius
+1  A: 

This has always bothered me too, so I wrote a quick python/expect script to replay ghci_history at the beginning of each ghci session.

It's not very polished. For example it always replays the whole history and that could be slow.

Daniel Velkov
There is also always the risk that sometime in the session you did a :! that you don't want repeated...
Gaius
Probably the :___ commands should be filtered. And of course you cannot guard against everything.
Daniel Velkov