ocaml doesn't load .ocamlinit in script mode - ocaml

I find that when I run ocaml in terminal, ie, in interactive mode, it will load .ocamlinit. However, when I run ocaml test.ml, ie, in script mode, it doesn't load .ocamlinit file. This actually causes some trouble for me, since I have the following setup in my .ocamlinit:
let () =
try Topdirs.dir_directory (Sys.getenv "OCAML_TOPLEVEL_PATH")
with Not_found -> ()
;;
#use "topfind";;
#thread;;
#camlp4o;;
#require "core.top";;
#require "core.syntax";;
So when I run in interactive mode, #use "topfind" will be executed and I can open other libraries in my code. But as .ocamlinit is not loaded in script mode, when I run ocaml test.ml in terminal, with test.ml like this:
open Core.Std;;
let () = print_endline "hello world"
It will fail with error: "Error: Unbound module Core".
My question is:
How to fix this so that when running ocaml in script mode, the .ocamlinit file will also be loaded?
Why the ocaml toplevel system doesn't load .ocamlinit file in script mode?
ps. The OCaml version is 4.01.0

I think that's a "bug" (or at least unexpected behaviour) in the toplevel. This could be fixed in future versions of OCaml. I don't have a satisfying workaround to propose, besides ocaml -noprompt < test.ml (which is not equivalent as you will get some noisy output from the toplevel instead of just your file executed), or of course compiling the program and running it (which may be as simple as ocamlbuild test.byte && ./test.byte).

Related

unbound module Base

I am following this tutorial for OCaml when I try to write this program in a file and then compile and execute with dune.
open Base
open Stdio
let rec read_and_accumulate accum =
let line = In_channel.input_line In_channel.stdin in
match line with
| None -> accum
| Some x -> read_and_accumulate (accum +. Float.of_string x)
let () =
printf "Total: %F\n" (read_and_accumulate 0.)
However I get the error 'unbound module Base'. Looking online I found the solution of adding #require “base”;; to the .ocamlinit file and that allows me to use the module in utop but it still won't work with running a file using dune. How can I run this program from a file?
With the small amount of informations you're giving I can only guess that you didn't write a proper dune file. It should look like this::
(executable
(name read_and_acc)
(libraries base))

Run MetaOCaml code

I have just installed BER MetaOCaml with the following :
$ opam update
$ opam switch 4.02.1+BER
$ eval `opam config env`
and I am not able to run MetaOCaml code in tuareg toplevel or simply ocaml toplevel. Following code :
let a = .<1+2>.;;
results in
Error: Reference to undefined global `Trx'
I have tried #load "trx.cma" but it cannot find the file.
Answer edit :
metaocaml is the right executable.
After adding this :
`(defun tuareg-run-metaocaml ()
"Run an OCaml toplevel process. I/O via buffer `*ocaml-toplevel*'."
(interactive)
(tuareg-run-process-if-needed
"/usr/bin/opam config exec -- metaocaml")
(display-buffer tuareg-interactive-buffer-name))
(add-hook 'tuareg-mode-hook
' (lambda ()
(define-key tuareg-mode-map (kbd "C-c M-s")
'tuareg-run-metaocaml)))`
To my .emacs, I am now able to run MetaOCaml with C-c M-s.

Compiling program that uses Lwt_term

I have the following code in OCaml:
open Lwt
open Lwt_term
let () = Lwt_main.run (
lwt l = Lwt_read_line.read_line ~prompt:[text "foo> "] ())
when I try to compile using
ocamlfind ocamlc -package lwt cli.ml - o cli.byte
it I get the following error:
File "cli.ml", line 2, characters 0-13:
Error: Unbound module Lwt_term
I know it's unrelated to the problem above, but from utop I can open Lwt but I still can't open Lwt_term. What am I doing wrong?
Source file is located there so I bet that you need lwt.text package
Not really a real answer to the original question, but I have ended up using Core to accomplish it. The enlightenment came from finding the readline_test.ml file in a tests folder in the Core library (https://github.com/janestreet/core_extended/blob/master/lib_test/readline_test.ml).
Following that example it was really easy to implement readline-like functionality.

How to load ocamlmktop result in aquamacs?

I am basically executing:
ocamlmktop -o mytoplevel 1.cmo 2.cmo
and I get by an executable toplevel. The question is how do I make aquamacs run that toplevel?
It depends of the Emacs mode that you use to develop in OCaml under Aquamacs. As tuareg-mode is by far the most popular choice, I consider this case.
You usually start an OCaml toplevel with the command M-x tuareg-run-ocaml which prompts for a toplevel to start. You can here enter the path to your custom toplevel.
The toplevel proposed by tuareg-run-ocaml is actually the value of the variable tuareg-interactive-program, you can take advantage of this to define a custom tuareg-run-mytoplevel function with:
(defun tuareg-run-mytoplevel ()
(interactive)
(let ((tuareg-interactive-program "/path/to/mytoplevel"))
(tuareg-run-ocaml)))
If you put this definition in your ~/.emacs, you can then use the command M-x tuareg-run-mytoplevel to start your own toplevel.

Regular Expressions in OCaml

I want to use regexps in OCaml and it seems that Str module provides these functionalities.
So I tried with a simple program:
open Str
let regx = regexp "."
but it gives me the following error
File "lol.ml", line 1, characters 0-1:
Error: Error while linking lol.cmo:
Reference to undefined global `Str'
As if module is not present but if I remove open Str it says that regexp is an unbound value.
I don't get what kind of issue it is, Str should be a standard module (according to http://caml.inria.fr/pub/docs/old-311/libref/Str.html) so I'm clueless.. the only think I thought is that signature (mli) is present but implementation (ml) is not.
I'm running Objective Caml version 3.11.0 according to ocaml tool.
Can anyone help me figuring this out?
Thanks in advance
From the manual:
Programs that use the str library must be linked as follows:
ocamlc other options str.cma other files
ocamlopt other options str.cmxa other files
Or you can put
#load "str.cma";;
if you are doing it in the interpreter
As an alternative to the Str module there's also Re2.
Install it using opam install re2
Use the module in your_file.ml like this:
open Re2.Std
open Re2.Infix
let change input_text = Re2.rewrite_exn ~/"change this" "to that" input_text
let () = printf "%s" (change "change this")
Compile with ocamlbuild -use-ocamlfind -package re2 -package core -tag thread your_file.byte