correct way to invoke a function in OCaml - ocaml

I just recently started to learn OCaml, and I have a small issue
I'm trying to generate a series of numbers with the following function
let new_num =
let cpt = ref (-1) in
fun () -> incr cpt; Printf.sprintf "__number_%i" !cpt
When I run ocaml in a terminal I can get a number with something like:
let n = new_num()
But when I add the above function to an existing file (that works, just provided to me) and try to call it like this, I get an error on the line containing with the call to the new_num function
let matching_function i = match i with
| case1 -> ... (* a code that works fine*)
| C(e,s1,s2)->
let n1 = new_num() in
n1
let n2 = new_num() in
n2
let code_e = trl e in (* trl is a working function somewhere else in my code)
code_e
(* rest of code and print n1,n2*)
if I remove the following part and run the file everything works perfectly.
let n1 = new_num() in
n1
let n2 = new_num() in
n2
I don't understand why this works in terminal interpreter but not when I run it in a .ml file? Can someone please explain it to me and help call it correctly? (sorry for the novice question)

The code in the file is not syntactically valid, that's all that's going on.
You can't have this:
let n1 = new_num () in n1
let ...
The second let isn't syntactically valid at that point.
You almost certainly want something like this:
let n1 = new_num () in
let n2 = new_num () in
...
This defines n1 and n2 for later use in the code.
The reason it works in the interpreter is that you're not typing in this same code.
Here's what you actually see if you type the erroneous lines into the toplevel (the interpreter):
# let n1 = new_num () in n1
let n2 = new_num () in n2;;
Error: Syntax error
If you add ;; between the two lines it is accepted (though it doesn't actually define top-level values named n1 and n2). But this isn't the same code. The ;; has a syntactic effect.
As a side comment, this expression:
let n1 = new_num () in n1
is exactly equivalent to this expression:
new_num ()
In particular, it doesn't define a value n1 that you can use later. The scope of the definition of v in let v = e1 in e2 is just e2.

Related

OCaml initializing list in loop for

I am a beginner with OCaml. I would like to skip the first element of my list.
Here is my list:
let l = [1;2;3;4;5;6;7;2;1];;
I want to use this in my FOR:
let l = List.tl l;
here is my full code:
let l = [1;2;3;4;5;6;7;2;1];;
let n = 1;;
let counter = ref 0;;
for i = 0 to (List.length l) do
if List.hd l = n then counter := !counter + 1;
print_int(!counter);
print_string("\n");
let l = List.tl l
done;;
But I have errors in the DONE and it says syntax error.
Can anyone help me please?
Your problem is that let always requires a matching in. The full expression looks like this:
let var = expr1 in expr2
Since you're missing the in part, you get a syntax error.
However, the deeper problem is that you're trying to modify the value of l. The way you have defined l, it's immutable. You can't change its value. If you want to be able to change its value you can define it as a reference, as you have done for counter.
(There is another form of let used at the top level of a module. This form doesn't have a matching in. But your code isn't defining a top-level name, so this is not relevant.)

Need and purpose of `()` and `in` in ocaml code

I am trying to understand Ocaml and running following code from here:
let rec fib n =
if n < 2 then 1 else fib (n-1) + fib (n-2);;
let main () =
let arg = int_of_string Sys.argv.(1) in
print_int (fib arg);
print_newline ();
exit 0;;
main ();;
However, I cannot understand why () and in are needed and why following code (which is much cleaner) does not work:
let rec fib n =
if n < 2 then 1 else fib (n-1) + fib (n-2);;
let main =
let arg = int_of_string Sys.argv.(1);
print_int (fib arg);
print_newline;
exit 0;; (* Line 7. Error is coming from here.*)
main;;
Above code gives following error:
File "fib_simpler.ml", line 7, characters 8-10:
Error: Syntax error
I notice that removing () only give warning, while removing in gives error and program execution stops.
Keeping in and () after print_newline removes all warnings and errors. So () is not really needed with main keywords.
Above is shown in comments below:
let rec fib n = (*(n) also works here*)
if n < 2 then 1 else fib (n-1) + fib (n-2);;
let main () = (*removing () here does not matter*)
let arg = int_of_string Sys.argv.(1) in (* in keyword is essential here*)
print_int (fib arg);
print_newline (); (*removing () causes warning *)
exit 0;;
main ();; (*removing () here does not matter*)
Any explanation will be appreciated.
OCaml is an expression-based language. It does not have statements, and therefore ; is not a statement terminator, but a sequence operator (similar to the comma operator of C). <expr1>; <expr2> is approximately just a short-hand for let () = <expr1> in <expr2>. It evaluates expr1, discards its value, then evaluates expr2 and returns that value.
let <pattern> = <expr1> in <expr2> is an expressions which binds the result of expr1 according to <pattern>, which may just be a simple identifier or a more complex record pattern for example, in the context of expr2. The bindings created by <pattern> will not exist outside expr2.
Using (), called "unit" in a binding defines a function. If you omit the argument, you're not defining a function, just a value. The difference is that a value is evaluated immediately, and just once, while a function will be evaluated when it is "called" by applying arguments to it. A function that expects () as an argument must be given () as the argument to execute it, otherwise you're just passing the function itself around. And if you're just discarding it, as you do above, that is almost always an error. Hence the warning.
In short:
let arg = int_of_string Sys.argv.(1); ... without an in separating two expressions is a syntax error. The compiler just doesn't realize it until it gets to the end of the current expression and discovers there is no in to be found there.
let main () =... defines a function
let main = ... defines a value
print_newline (); ... applies the argument () to print_newline, thereby executing it, then discards the return value
print_newline; ... doesn't really do anything
Finally, if you're just going to execute main once, you can reduce
let main () = ...;;
main;;
to
let () = ...;;
You don't need a named function unless you're going to use it multiple times.

OCaml Factorial Function with Restrictions

I'm trying to learn OCaml on my own, and I've reached imperative programming. I found this little exercise that I'm just completely stuck on how to even approach. It seems so simple, but I think my understanding is just lacking.
The problem asks me to write the function for factorial without using the rec keyword, and without loops. It's supposed to teach me the environment model, but that's also confusing to me.
My first thought was to try something like this:
let factorial =
let f = ref (fun n -> 0) in
let temp_factorial n =
if n = 0
then 1
else
begin
f := n * !f*(n-1)
!f
end
But I'm not sure if this works. Any help would be greatly appreciated :)
Your code is a little strange and wrong, but the basic idea is workable. Once you have a reference f to a function of type int -> int, you can use !f freely in later code. In fact you can assign f so it refers to a function that uses !f. This is equivalent to recursion, but it uses the imperative part of OCaml.
let f = ref (fun n -> n + 1)
f :=
(fun n ->
if n < 2 then 1
else (* ... left as an exercise ... *)
)
let factoral n = !f n
The key is that the part left as an exercise can use !f.

How to reduce code clutter in this function?

The function tally below is really simple: it takes a string s as argument, splits it on non-alphanumeric characters, and tallies the numbers of the resulting "words", case-insensitively.
open Core.Std
let tally s =
let get m k =
match Map.find m k with
| None -> 0
| Some n -> n
in
let upd m k = Map.add m ~key:k ~data:(1 + get m k) in
let re = Str.regexp "[^a-zA-Z0-9]+" in
let ws = List.map (Str.split re s) ~f:String.lowercase in
List.fold_left ws ~init:String.Map.empty ~f:upd
I think this function is harder to read than it should be due to clutter. I wish I could write something closer to this (where I've indulged in some "fantasy syntax"):
(* NOT VALID SYNTAX -- DO NOT COPY !!! *)
open Core.Std
let tally s =
let get m k =
match find m k with
| None -> 0
| Some n -> n ,
upd m k = add m k (1 + get m k) ,
re = regexp "[^a-zA-Z0-9]+" ,
ws = map (split re s) lowercase
in fold_left ws empty upd
The changes I did above fall primarily into three groups:
get rid of the repeated let ... in's, consolidated all the bindings (into a ,-separated sequence; this, AFAIK, is not valid OCaml);
got rid of the ~foo:-type noise in function calls;
got rid of the prefixes Str., List., etc.
Can I achieve similar effects using valid OCaml syntax?
Readability is difficult to achieve, it highly depends on the reader's abilities and familiarity with the code. I'll focus simply on the syntax transformations, but you could perhaps refactor the code in a more compact form, if this is what you are really looking for.
To remove the module qualifiers, simply open them beforehand:
open Str
open Map
open List
You must open them in that order to make sure the List values you are using there are still reachable, and not scope-overridden by the Map ones.
For labelled parameters, you may omit the labels if for each function call you provide all the parameters of the function in the function signature order.
To reduce the number of let...in constructs, you have several options:
Use a set of rec definitions:
let tally s =
let rec get m k =
match find m k with
| None -> 0
| Some n -> n
and upd m k = add m k (1 + get m k)
and re = regexp "[^a-zA-Z0-9]+"
and ws = map lowercase (split re s)
in fold_left ws empty upd
Make multiple definitions at once:
let tally s =
let get, upd, ws =
let re = regexp "[^a-zA-Z0-9]+" in
fun m k ->
match find m k with
| None -> 0
| Some n -> n,
fun g m k -> add m k (1 + g m k),
map lowercase (split re s)
in fold_left ws empty (upd get)
Use a module to group your definitions:
let tally s =
let module M = struct
let get m k =
match find m k with
| None -> 0
| Some n -> n
let upd m k = add m k (1 + get m k)
let re = regexp "[^a-zA-Z0-9]+"
let ws = map lowercase (split re s)
end in fold_left ws empty M.upd
The later is reminiscent of the Sml syntax, and perhaps better suited to proper optimization by the compiler, but it only get rid of the in keywords.
Please note that since I am not familiar with the Core Api, I might have written incorrect code.
If you have a sequence of computations on the same value, then in OCaml there is a |> operator, that takes a value from the left, and applies in to the function on the right. This can help you to "get rid of" let and in. What concerning labeled arguments, then you can get rid of them by falling back to a vanilla standard library, and make your code smaller, but less readable. Anyway, there is a small piece of sugar with labeled arguments, you can always write f ~key ~data instead of f ~key:key ~data:data. And, finally, module names can be removed either by local open syntax (let open List in ...) or by locally shorcutting it to a smaller names (let module L = List in).
Anyway, I would like to show you a code, that contains less clutter, to my opinion:
open Core.Std
open Re2.Std
open Re2.Infix
module Words = String.Map
let tally s =
Re2.split ~/"\\PL" s |>
List.map ~f:(fun s -> String.uppercase s, ()) |>
Words.of_alist_multi |>
Words.map ~f:List.length

Is this a reasonable implementation of the quadratic Bézier function in OCaml?

A friend came across a quadratic Bézier curve function in his codebase that used a gigantic rats nest of a switch table to perform the computation. He challenged me to find a single, short expression that would allow him to replace the gigantic block of code.
In attempting to satisfy two different curiosities, I thought I'd try implementing the function in OCaml. I'm a very novice OCaml programmer and I'm also unfamiliar with the function and this specific implementation is hard to come by via Google.
Critiques on both the function's performance/correctness as well as its implementation are very much appreciated.
Implementation of Quadratic Bézier Curve:
let rec b2 n =
let p1 = -10. in
let p2 = 10. in
let q = n*.n in
let rec b2i n i hd =
if i > n then
List.rev hd
else
let t = i /. n in
b2i n (i+.1.) ((((1.-.t)**2.)*.p1+.(2.*.t*.(1.-.t)*.q)+.(t**2.)*.p2) :: hd)
in
b2i n 0. []
;;
let floatprint lst =
List.iter (fun f -> Printf.printf "%f; " f) lst ;;
floatprint (b2 8.);;
b2 isn't recursive, so no need for [let rec b2 n =]. Since n never changes, no need to have it as argument to b2i, just use n from the enclosing scope. Your inner function should depend on p0, p1 and p2, but I see it depending on -10., n**2 and 10. The function also has the form of a map from [ 0.0; 1.0; 2.0; ...; n.0] to the final values. Could you write it:
let b i =
let t = i /. n in
let tminus = (1.-.t) in
(tminus *. tminus *. p0) +. (2. *. t *. tminus *. p1) +. (t *. t * p2)
in
List.map b ([generate list 1.0; 2.0; ... n.0])
A function to generate the list 1.0...n.0 could be: (for small n)
let rec count m n = if m > n then [] else m :: (count (m+.1.) n)
I have two suggestions:
You should call List.rev after b2i returns so ocaml can exploit it's tail-recursion optimizations. I am not sure how well OCaml will deal with the current implementation, List.rev is tail-recursive though. You'll notice that in this post it is done like that.
Also, you can make the resolution of the iteration be an optional argument like ?(epsilon=0.1).
As an ocaml programmer I don't see much wrong here aside from that --as long as P1 and P2 are in fact constants. Compile it down and see what the difference in assembly is between moving List.rev inside or out of the tail-recursion.