OCaml syntax confusion - syntax

When I first began using the in statement I thought it was pretty straightforward and made sense. However, these code examples made me question how well I understand them.
let fun1 x = let fun2 y = y + 1 in fun2(x);;
val fun1 : int -> int = <fun>
I think this can be thought of as declaring fun2, and then applying it to call fun2 with a variable x that you get from fun1.
let sum1 i = let sum2 j = i+j in sum2;;
val sum1 : int -> int -> int = <fun>
This one confuses me much more and raises more questions. I don't really know how to interpret this. Is it that sum1 was declared to be used in sum2? If so why does in apply to the outer function and not the inner function like it did in the first example?
Any help in interpreting these code snippets would be appreciated.

There's no such thing as an in statement. There are let definitions of the form let [rec] pattern = expression {and pattern = expression} and let expressions of the form let [rec] pattern = expression {and pattern = expression} in expression (where [] means "optional" and {} means "zero or more"). So in is merely a part of the syntax of let expressions.
Is it that sum1 was declared to be used in sum2?
No. sum2 is defined to be used inside sum1 just like in your first example. sum1 i simply returns sum2 as its result. Another way to write it without giving a name to the function being returned would be:
let sum1 i = fun j -> i + j
Or even:
let sum1 i j = i + j

Related

How is a reference counter implemented at compile time?

Here is a made up set of function calls (I tried to make it complicated but perhaps it is easy).
function main(arg1, arg2) {
do_foo(arg1, arg2)
}
function do_foo(a, b) {
let x = a + b
let y = x * a
let z = x * b
let p = y + z
let q = x + z
let r = do_bar(&p)
let s = do_bar(&q)
}
function do_bar(&p, &q) {
*p += 1
*q += 3
let r = &p * &q
let s = &p + &q
let v = do_baz(&r, &s)
return &v
}
function do_baz(&a, &b) {
return *a + *b
}
How do you generally go about figuring out the liveness of variables and where you can insert instructions for reference counting?
Here is my attempt...
Start at the top function main. It starts with 2 arguments. Assume there is no copying that occurs. It passes the actual mutable values to do_foo.
Then we have x. X owns a and b. Then we see y. y is set to x, so link the previous x to this x. By r, we don't see x anymore, so perhaps it can be freed.... Looking at do_bar by itself, we know basically that p and q can't be garbage collected within this scope.
Basically, I have no idea how to start implementing an algorithm to implement ARC (ideally compile time reference counting, but runtime would be okay for now too to get started).
function main(arg1, arg2) {
let x = do_foo(arg1, arg2)
free(arg1)
free(arg2)
free(x)
}
function do_foo(a, b) {
let x = a + b
let y = x * a
let z = x * b
let p = y + z
free(y)
let q = x + z
free(x)
free(z)
let r = do_bar(&p)
let s = do_bar(&q)
return r + s
}
function do_bar(&p, &q) {
*p += 1
*q += 3
let r = &p * &q
let s = &p + &q
let v = do_baz(&r, &s)
free(r)
free(s)
return &v
}
function do_baz(&a, &b) {
return *a + *b
}
How do I start with implementing such an algorithm. I have searched for every paper on the topic but found no algorithms.
The following rules should do the job for your language.
When a variable is declared, increment its refcount
When a variable goes out of scope, decrement its refcount
When a reference-to-variable is assigned to a variable, adjust the reference counts for the variable(s):
increment the refcount for the variable whose reference is being assigned
decrement the refcount for the variable whose references was previously in the variable being assigned to (if it was not null)
When a variable containing a non-null reference-to-variable goes out of scope, decrement the refcount for the variable it referred to.
Note:
If your language allows reference-to-variable types to be used in data structures, "static" variables, etcetera, the rules abouve need to be extended ... in the obvious fashion.
An optimizing compiler may be able to eliminate some refcount increments and decrements.
Compile time reference counting:
There isn't really any such thing. Reference counting is done at runtime. It doesn't make sense to do it at compile time.
You are probably talking about analyzing the code to determine if runtime reference counting can be optimized or entirely eliminated.
I alluded to the former above. It is really a kind of peephole optimization.
The latter entails checking whether a reference-to-variable can ever escape; i.e. whether it could be used after the variable goes out of scope. (Try Googling for "escape analysis". This is kind of analogous to the "escape analysis" that a compiler could do to decide if an object could be allocated on the stack rather than in the heap.)

Getting a random number in a function in OCAML OR Telling compiler to evaluate function each time

I'm new to OCAML and was playing around with putting a marker on a random 5X5 square. I've written the example program below. "silly_method1" works but notice that it takes an argument. I don't really have argument to pass in for what I want. I'm just asking for a random number to create my robot on a particular square:
let create = {x = ( Random.int 4); y=3; face = North}
However, I get the same location each time. This makes sense to me... sort of. I'm assuming that the way I've set it up, "create" is basically a constant. It's evaluated once and that's it! I've fixed it below in silly_method2 but look how ugly it is!
let silly_method2 _ = (Random.int 10)
Every time I have to call it, I have to pass in an argument even though I'm not really using it.
What is the correct way to do this? There must be some way to have a function that takes no arguments and passes back a random number (or random tuple, etc.)
And possibly related... Is there a way to tell OCaml not to evaluate the function once and save the result but rather recalculate the answer each time?
Thank you for your patience with me!
Dave
let _ = Random.self_init()
let silly_method1 x = x + (Random.int 10)
let silly_method2 _ = (Random.int 10)
let report1 x = (print_newline(); print_string("report1 begin: "); print_int (silly_method1 x); print_string("report1 end"); print_newline(); )
let report2 y = (print_newline(); print_string("report2 begin: "); print_int(silly_method2 y ); print_string("report2 end"); print_newline(); )
let _ = report1 3
let _ = report1 3
let _ = report1 3
let _ = report2 3
let _ = report2 3
let _ = report2 3
The idiomatic way to define a function in OCaml that doesn't take an argument is to have the argument be (), which is a value (the only value) of type unit:
# let f () = Random.int 10;;
val f : unit -> int = <fun>
# f ();;
- : int = 5
# f ();;
- : int = 2
OCaml doesn't save function results for later re-use. If you want this behavior you have to ask for it explicitly using lazy.

F# function takes too many arguments or used in a context not expected

I'm trying to implement a cost function and I currently have
let computeCost (X : Matrix<double>) (y : Vector<double>) (theta : Vector<double>) =
let m = y.Count |> double
let J = (1.0/(2.0*m))*(((X*theta - y) |> Vector.map (fun x -> x*x)).Sum)
J
For some reason I get an error on the half after the first * saying "This function takes too many arguments, or is used in a context where a function is not expected."
However, when I do this
let computeCost (X : Matrix<double>) (y : Vector<double>) (theta : Vector<double>) =
let m = y.Count |> double
let J = (((X*theta - y) |> Vector.map (fun x -> x*x)).Sum)
J
It works perfectly fine and it says that val J:float which is what I expect. But as soon as add in the second piece which is the (1.0/(2.0*m)) part I get the error. I have parenthesis around everything so I don't see how it can be some partial function being applied or something along those lines. I'm sure it's something dumb but I can't seem to figure it out.
Nevermind, I'm dumb and I fell back into my C# ways of using .Sum() The actual way of using it is
let computeCost (X : Matrix<double>) (y : Vector<double>) (theta : Vector<double>) =
let m = y.Count |> double
let J = (1.0/(2.0*m)) * (((X*theta - y) |> Vector.map (fun x -> x*x)) |> Vector.sum)
J
And this seemed to fix it.

Remove the first char to extract an integer (unhandled exception: Subscript)

I'm trying to write a function which extracts only the integer in a string.
All my strings have the format Ci where C is a single character and i is an integer. I would like to be able to remove the C from my string.
I tried something like this :
fun transformKripke x =
if size x > 1
then String.substring (x, 1, size x)
else x
But unfortunately, I get an error like unhandled exception: Subscript.
I assume it's because sometimes my string will be empty and size of empty string is not working. But I don't know how to make it work... :/
Thanks in advance for your help
Best Regards.
The problem is calling String.substring (x, 1, size x) when x is not long enough.
The following should fix your immediate problem:
fun transformKripke s =
if size s = 0
then s
else String.substring (s, 1, size s)
or slightly prettier:
fun transformKripke s =
if size s = 0
then s
else String.extract (s, 1, NONE) (* means "until the end" *)
But you may want to consider naming your function something more general so that it can be useful in more senses than performing a Kripke transform (whatever that is). For example, you may want to be able to extract an actual int the first time one occurs anywhere in a string, regardless of how many non-integer characters that precede it:
fun extractInt s =
let val len = String.size s
fun helper pos result =
if pos = len
then result
else let val c = String.sub (s, pos)
val d = ord c - ord #"0"
in case (Char.isDigit c, result) of
(true, NONE) => helper (pos+1) (SOME d)
| (true, SOME ds) => helper (pos+1) (SOME (ds * 10 + d))
| (false, NONE) => helper (pos+1) NONE
| (false, SOME ds) => SOME ds
end
in helper 0 NONE
end
My mistake was stupid,
The string is finishing at size x -1 not size x. So now it's correct :
fun transformKripke x =
if size x > 1
then String.substring (x, 1, (size x)-1)
else x
Hope it will help ! :)

Array Out Of Bounds F#

While attempting to learn more about sorting algorithims and F#, I wrote an Insertion Sort in F#. I am a complete noob to F# and functional programming.
let insert (a: array<int>) i item =
i = i - 1
while i >= 0 && item < a.[i] do
a.[i + 1] = a.[i]
i = i - 1
a.[i + 1] = item
a
let sort (a: array<int>) =
for i in 1 .. (a.Length - 1) do
a = insert a i a.[i]
a
let a = [|3; 4; 1; 3;|]
a = sort a
for i in a do
printfn "%d" i
The code compiles fine, but when i run the executable...
Unhandled Exception: System.IndexOutOfRangeException: Index was outside the boun
ds of the array.
at Isort.insert(Int32[] a, Int32 i, Int32 item)
at Isort.sort(Int32[] a)
at <StartupCode$isort>.$Isort.main#()
The exception is kind of unhelpful, as it doesn't say where the out of range exception was...
Is there a way to fix this error in my code?
Several comments:
F# values are immutable by default. If you want to modify values, declare them as mutable.
= is equality while <- is assignment to mutable values.
Pay attention to warnings in F#. In this case, there are a lot of errors since you ignore values of comparisons.
An improved version:
let insert (a: int []) j item =
let mutable i = j - 1
while i >= 0 && item < a.[i] do
a.[i + 1] <- a.[i]
i <- i - 1
a.[i + 1] <- item
let sort (b: int []) =
let a = Array.copy b
for i in 1 .. (a.Length - 1) do
insert a i a.[i]
a
let a = [|3; 4; 1; 3; 5; 6; 5|]
let a' = sort a
for i in a' do printfn "%d" i
I modified names of a few variables for clarity. Moreover, auxiliary function insert could return unit while sort has better return a new copy instead of mutating the input array.

Resources