Printing ocaml function after compiling - ocaml

It's my first day with ocaml. Enjoying it so far. I wanted to figure out if there is a way to print the result of a function. Here's an example based on Project Euler #5.
My code is:
let rec gcd a b =
if b==0 then a
else (gcd b (a mod b));;
let rec myans n anssofar=
if n==1 then anssofar
else (myans (n-1) ((anssofar*(n-1))/(gcd anssofar (n-1))));;
Printf.printf "%d\n" (myans 20 20)
This works fine. I then compile it using:
$ ocamlc -o PE0005 PE0005.ml
And then run it using
$ ./PE0005
And it spits out the answer.
Now, suppose I wanted to work out myans 10 10. It seems perverse to do what I have been doing which is to go back, edit the last line to
Printf.printf "%d\n" (myans 10 10)
and then recompile and rerun. The function has already been defined and compiled. Is there some way I can print out the answer without recompiling?
Any hints and tips are welcome.

One possibility is to run your code in the toplevel (the OCaml read/eval/print loop). This lets you experiment more easily.
$ ocaml
# #use "PE0005.ml";;
val gcd : int -> int -> int = <fun>
val myans : int -> int = <fun>
232792560
- : unit = ()
# myans 10 10;;
- : int = 2520
Another possibility is to rewrite your code to get the argument from the command line. This is what you would do in practice for a compiled command-line program.
let main () =
if Array.length Sys.argv < 3 then (
Printf.eprintf "need two integer arguments\n";
exit 1
) else (
Printf.printf "%d\n"
(myans (int_of_string Sys.argv.(1)))
)
let () = main ()
This is how it works when you run it:
$ ocamlc -o PE0005 PE0005.ml
$ ./PE0005 20 20
232792560
$ ./PE0005 10 10
2520

You can use sys.argv to get command line arguments and pass the values at runtime.

Related

ocamlbuild with Toploop/TopLevel

I'm looking to implement an eval function like in this answer here: https://stackoverflow.com/a/33293116/
However, when I go to compile my code sample:
let eval code =
let as_buf = Lexing.from_string code in
let parsed = !Toploop.parse_toplevel_phrase as_buf in
ignore (Toploop.execute_phrase true Format.std_formatter parsed)
let rec sum_until n =
if n = 0
then 0
else n + sum_until (n - 1);;
let a = print_string "Enter sum_until x where x = an int: "; read_line ();;
print_int eval a;;
with the following:
ocamlbuild UserInputEval.native -pkgs compiler-libs,compiler-libs.toplevel
I am getting the error:
File "_none_", line 1: Error: Cannot find file
/usr/lib/ocaml/compiler-libs/ocamltoplevel.cmxa Command exited with
code 2.
I have checked the compiler-libs directory and I don't have an ocamltoplevel.cmxa file but I do have an ocamltoplevel.cma file.
I'm wondering if this is a simple fix? I'm a bit new to ocaml so I'm not sure how to go about fixing this. Thanks!
The toplevel library is only available in bytecode mode:
ocamlbuild UserInputEval.byte -pkgs compiler-libs,compiler-libs.toplevel
Note also that the compiler-libs package may need to be installed separately (this is at least the case for archlinux).
Nevertheless, your code is probably not doing what are you expecting: you are only feeding the user input to the toplevel interpreter without reading anything from the toplevel state.
If you just want to read an integer, you can do it with simply:
let a = print_string "Enter sum_until x where x = an int: \n"; read_int ();;
print_int (sum_until a);;
without any need for compiler-libs.

OCaml Triple every number in a list of integers

So I need to write a function that will triple every number in a list of integers
Here is what I have so far:
let number = [1; 2; 3; 4];;
let rec print_list_int myList = match myList with
| [] -> print_endline "This is the end of the int list!"
| head::body ->
begin
print_int head * 3;
print_endline "";
print_list_int body *3
end
;;
print_list_int number;;
It doesn't seem to do anything useful, any ideas where I went wrong? Need it outputting but it also doesn't do that. Thanks in advance! :)
This expression:
print_int head * 3
is interpreted like this:
(print_int head) * 3
Because function calls (application) have high precedence. You need to parenthesize like this:
print_int (head * 3)
The similar case below is a different problem: (print_list_int body) * 3 doesn't make sense but print_list_int (body * 3) also doesn't make sense. You can't multiply a list by 3. However, you don't need to multiply at this call. The print_list_int function will (recursively) do the multiplying for you.
Update
If I make the changes I hinted at above, I see this in the OCaml toplevel:
val print_list_int : int list -> unit = <fun>
# print_list_int number;;
3
6
9
12
This is the end of the int list!
- : unit = ()
#
Note that the most elegant way to achieve what you're trying to do is to use List.iter. It applies a given function (returning unit) to each element of a List.
let print_triples = List.iter (fun x ->
print_endline (string_of_int (3*x))
);;
val print_triples : int list -> unit = <fun>
And here you go:
# print_triples [1;2;3;4;5];;
3
6
9
12
15
- : unit = ()

How to create a big number of threads in OCaml?

I found a topic in the Racket group about the performance of channel creating.
I want to write a OCaml's version to test.
let post (c,x) = Event.sync (Event.send c x);;
let accept c = Event.sync (Event.receive c);;
let get_chan c = let n = accept c in print_int n;print_newline ();;
let chan_trans (old_chan, new_chan) =
let s = accept old_chan in
post (new_chan,(s+1));;
let rec whisper count init_val =
let rec aux n chan =
if n >= count then chan
else
let new_chan = Event.new_channel ()
in Thread.create chan_trans (chan, new_chan);
aux (n+1) new_chan
in let leftest_chan = Event.new_channel ()
in let t0 = Thread.create post (leftest_chan, init_val)
in let rightest_chan = aux 0 leftest_chan
in get_chan rightest_chan;;
whisper 10000 1;;
The question is, when I tested for whisper 1000 1, it produced 1001 as expected. However, when I tried to test whisper 10000 1, there's an error as
Fatal error: exception Sys_error("Thread.create: Resource temporarily unavailable")
I used this command to compile and run
ocamlc -thread unix.cma threads.cma -o prog whisper.ml&&./prog -I
+threads
OCaml Thread module uses the real system (kernel) threads. The total number of threads is bounded by the kernel:
cat /proc/sys/kernel/threads-max
251422
You can increase this of course,
echo 100000 > /proc/sys/kernel/threads-max
but a better approach would be to treat threads as a resource and manage them correspondingly.
let rec whisper count init_val =
let rec aux n t chan =
if n >= count then chan
else
let new_chan = Event.new_channel () in
let t' = Thread.create chan_trans (chan, new_chan) in
Thread.join t;
aux (n+1) t' new_chan in
let leftest_chan = Event.new_channel () in
let t = Thread.create post (leftest_chan, init_val) in
let rightest_chan = aux 0 t leftest_chan in
get_chan rightest_chan
In that case it will run with any size of the pipeline. For example:
$ ocamlbuild -use-ocamlfind -tag thread -pkg threads ev.native
$ time ./ev.native
100001
real 0m1.581s
But this implementation of Chinese Whispers is very crude and inefficient. You shouldn't use heavyweight native threads for this (and neither go uses them). Instead, you should use cooperative lightweight threads from Lwt or Async libraries. This would be much efficient and nice.
Implementation with Lwt
This implementation follows closely the Go implementation from the blog post, but I think that we can do this more efficient and concise in OCaml without using mailboxes (but I'm not sure whether it will conform to the rules of the benchmark).
open Lwt.Infix
let whispers n =
let rec whisper i p =
if i < n then
Lwt_mvar.take p >>= fun x ->
whisper (i+1) (Lwt_mvar.create (x+1))
else Lwt_mvar.take p in
whisper 0 (Lwt_mvar.create 1)
let () = print_int ## Lwt_main.run (whispers 100000)
The results are:
$ ocamlbuild -use-ocamlfind -tag thread -pkg lwt.unix lev.native --
$ time ./lev.native
100001
real 0m0.007s
To compare with Go implementation on mine machine:
$ go build whispers.go
$ time ./whispers
100001
real 0m0.952s
"Slow" implementation
The code above is a completely honest reimplementation of the original Go version. But one of the reasons why it so fast, is that OCaml and Lwt is very clever, and although it creates 100_000 threads and 100_001 channels, no threads are ever got yielded to a background, since every time the whisper is called the channel already contains data, so the thread is in a ready state. As a result, this is just an efficient loop, that creates threads and channels. It can create a million threads in 50 ms.
So this is an idiomatic and correct way of doing things. But lets for the sake of true comparison mimick Go behavior. The following implementation will first eagerly create in the heap 100_001 channels, and 100_000 threads, waiting to transfer data from left to right channel. And only afterward it will put a value into the leftmost channel to provoke a chain of reaction. This would basically mimick what is happening in Go underneath the hood.
let whispers n =
let rec loop i p =
if i < n then
let p' = Lwt_mvar.create_empty () in
let _t =
Lwt_mvar.take p >>= fun x ->
Lwt_mvar.put p' (x+1) in
loop (i+1) p'
else Lwt_mvar.take p in
let p0 = Lwt_mvar.create_empty () in
let t = loop 1 p0 in
Lwt_mvar.put p0 1 >>= fun () -> t
$ time ./lev.native
100001
real 0m0.111s
So it is slightly slower, in fact it is 20 times slower than the previous implementation (I've used 1 million of threads to compare them), but it is still 10 times faster than the Go.
Reading the linked post it seems you might want to use lwt which is a "cooperative threads library for OCaml". The result would look something like this:
let whisper left right =
let%lwt n = Lwt_mvar.take right in
Lwt_mvar.put left (n+1)
let main () =
let n = 100_000 in
let%lwt () = Lwt_io.printf "With %d mvars!\n" n in
let leftmost = Lwt_mvar.create_empty () in
let rec setup_whispers left i =
if i >= n
then left
else let right = Lwt_mvar.create_empty () in
let () = Lwt.async (fun () -> whisper left right) in
setup_whispers right (i+1) in
let rightmost = setup_whispers leftmost 0 in
let%lwt () = Lwt_mvar.put rightmost 1 in
let%lwt res = Lwt_mvar.take leftmost in
Lwt_io.printf "%d\n" res
let () = Lwt_main.run (main ())
And then compiling and running it
$ ocamlbuild -use-ocamlfind -pkg lwt,lwt.ppx,lwt.unix whisper.native
$ time ./whisper.native
With 100000 mvars!
100001
real 0m0.169s
user 0m0.156s
sys 0m0.008s

Reading all characters in OCaml is too slow

I'm a beginner with OCaml and I want to read lines from a file and then examine all characters in each line.
As a dummy example, let's say we want to count the occurrences of the character 'A' in a file.
I tried the following
open Core.Std
let count_a acc string =
let rec count_help res stream =
match Stream.peek stream with
| None -> res
| Some char -> Stream.junk stream; if char = 'A' then count_help (res+1) stream else count_help res stream
in acc + count_help 0 (Stream.of_string string)
let count_a = In_channel.fold_lines stdin ~init:0 ~f:count_a
let () = print_string ((string_of_int count_a)^"\n"
I compile it with
ocamlfind ocamlc -linkpkg -thread -package core -o solution solution.ml
run it with
$./solution < huge_file.txt
on a a file with one million lines which gives me the following times
real 0m16.337s
user 0m16.302s
sys 0m0.027s
which is 4 times more than my python implementation. I'm fairly sure that it should be possible to make this go faster, but I how should I go about doing this?
To count the number of A chars in a string you can just use String.count function. Indeed, the simpliest solution will be:
open Core.Std
let () =
In_channel.input_all stdin |>
String.count ~f:(fun c -> c = 'A') |>
printf "we have %d A's\n"
update
A slightly more complicated (and less memory hungry solution), with [fold_lines] will look like this:
let () =
In_channel.fold_lines stdin ~init:0 ~f:(fun n s ->
n + String.count ~f:(fun c -> c = 'A') s) |>
printf "we have %d A's\n"
Indeed, it is slower, than the previous one. It takes 7.3 seconds on my 8-year old laptop, to count 'A' in 20-megabyte text file. And 3 seconds on a former solution.
Also, you can find this post interesting, I hope.

How to create a module OCaml and use it?

I'm new to this language/Tecnology
I have a simple question but I can not find answer:
I would like to create a my Module where you can enter OCaml simple functions / assignments such as the following
let rec gcd (m, n) = if m = 0 then n
   else gcd (n mod m, n);;
 
let one = 1;;
let two = 2;;
Use these functions to other programs OCaml
Every OCaml source file forms a module named the same as the file (with first character upper case). So one way to do what you want is to have a file named (say) numtheory.ml:
$ cat numtheory.ml
let rec gcd (m, n) = if m = 0 then n
else gcd (n mod m, n)
let one = 1
let two = 2
This forms a module named Numtheory. You can compile it and link into projects. Or you can compile it and use it from the OCaml toplevel:
$ ocamlc -c numtheory.ml
$ ocaml
OCaml version 4.01.0
# #load "numtheory.cmo";;
# Numtheory.one;;
- : int = 1
# Numtheory.gcd (4, 8);;
- : int = 8
(For what it's worth, this doesn't look like the correct definition of gcd.)