OCaml This is not a function; it cannot be applied - functional-programming

I have a function num_order rank -> int defined.
the following function call will cause a error
let dom_rank r1 r = (num_order r1) > (num_order r)
dom_rank Seven Eight
Line 1: Error: This expression has type int
This is not a function; it cannot be applied.
it seems to be the first line to be causing the problem... however when I remove the second line, the error is gone.

The statement
let dom_rank r1 r = (num_order r1) > (num_order r)
dom_rank Seven Eight
is the very same thing as
let dom_rank r1 r = (num_order r1) > (num_order r) dom_rank Seven Eight
or
let dom_rank r1 r = (num_order r1) > ((num_order r) dom_rank Seven Eight)
because function application takes precedence over binary operators like >. With this in mind, the error message of the compiler should be pretty clear.
To separate the two statements you would probably write them as
let dom_rank r1 r = (num_order r1) > (num_order r);;
dom_rank Seven Eight;;
in the interactive toplevel, or as
let dom_rank r1 r = (num_order r1) > (num_order r)
let dr78 = dom_rank Seven Eight
in a module definition, also giving a name to the value you compute.
The usual way to trigger a function only having a side effect is to use the idiosyncratic
let () = print_endline "Hello, World!"
Do not be confused by differences between using the OCaml interactive loop and regular programming. In the OCaml interactive loop, it is possible to evaluate a single expression, which has the side effect of printing the resulting value. When writing an OCaml program, evaluating expressions is an error, we should use let bindings instead. In the OCaml interactive loop, the ;; sequence can be used to separate phrases. While this is also supported for writing regular programs, this is often regarded as a hacky construct to enhance compatibility between code for the interactive toplevel and regular program code.
The ; is the sequence operator used to combine several expressions in one expression. It should be not confused with ;; which merely indicate the end of a sentence.

I need to add ;; at the end of the first line. It is also possible to write the following (I think this is more correct) :
let dom_rank r1 r = (num_order r1) > (num_order r)
let _ = dom_rank Seven Eight

Related

Sum of Odds in OCaml

I have some code written in OCaml
let rec sumodds n =
if (n mod 2)<>0 then
let sum = sumodds (n-1) in
n + sum
else sumodds(n-1);;
and I am trying to add up all odd numbers from 0 to n, but I am not sure how to make the program stop once n reaches zero. If I could get some help that would be awesome. If there are any other mistakes in the program, feel free to let me know what they are.
The way to get the function to stop is to test for the "stop condition". I.e., you need to add an if statement that tests whether you have reached such a low value for n that the result is obvious.
Very commonly a recursive function looks like this:
let rec myfun arg =
if is_trivial_value arg then
obvious_answer
else
let s = myfun (smallish_part_of arg) in
combine arg s
You just need to add a test for the trivial value of your argument n.
Update
As #Goswin_von_Brederlow points out, another very common pattern for recursive functions is this:
let rec myfun2 accum arg =
if is_trivial_vaue arg then
accum
else
myfun2 (combine arg accum) (smallish_part_of arg)
This is the tail recursive transformation of the above form. You can code in either form, but they are different. So you need to keep them straight in your mind. As an FP programmer you need to (and will pretty easily) learn to translate between the two forms.
just add "if n <= 0 then n" in the 2nd line

Store values generated by a for-loop. JuMP/Julia

It's amazing that the internet is totally void of this simple question (or similar). Or I'm just very bad at searching. Anyway, I simply want to store values generated by a for-loop in an array and print the array. Simple as that.
On every other language Matlab, R, Python, Java etc this is very simple. But in Julia I seem to be missing something.
using JuMP
# t = int64[] has also been tested
t = 0
for i in 1:5
vector[i]
println[vector]
end
I get the error
ERROR: LoadError: BoundsError
What am I missing?
You didn't initialize vector and you should call the method println like this following way, in Julia 1.0 :
vector = Array{Int,1}(undef, 5)
for i in 1:5
vector[i] = i
println(vector[i])
end
Or, more quickly, with a comprehension list :
vector = [i for i in 1:5]
for i in 1:5
println(vector[i])
end
Another possibility using push! method :
vector = []
for i in 1:5
push!(vector, i)
println(vector[i])
end

How do I perform a nested iteration?

I defined a function m(r,T,a,w) and I have vectors for the variables r,T,w.
What I want to do is to take the first element of each of those vectors and iterate my function for a in 1:T, then take the sum and repeat this iteration for the second element of those vectors and so on.
In the end I want to have a vector consisting of all the sums.
I would appreciate your help.
What I tried so far:
(W,R,LE are the vectors for the variables for w,r,T, respectively)
M = []
for w in W, r in R, T in LE
for a in 1:T
MM=sum(m(r,T,a,w))
push!(M,MM)
end
end
clearly Julia would not recognise what Im trying to do
The syntax:
for w in W, r in R, T in LE
...
does not iterate over the vectors at the same time. Rather, it is equivalent to the product:
for w in W
for r in R
for T in LE
...
It sounds like you want to iterate over those three vectors at the same time. In that case, you can use zip:
for (w,r,T) in zip(W,R,LE)
...
Matt's answer is correct, but you might want to improve a few other things, such as the types, and putting this in a function so that it isn't using a global variable. Do you know what the type of the sum is? Would a Float64 work, or a Int64?
For example:
function myfun(W, R, LE)
M = Vector{Float64}()
for (w, r, T) in zip(W, R, LE), a in T
push!(M, sum(m(r, T, a, w)))
end
M
end
Thanks for the very helpful comments. I managed to code what I wanted
MM = Vector{Float64}()
M = Vector{Float64}()
for (w, r, T) in zip(W, R, LE)
for a in 1:T
push!(MM, m(r,T,a,w))
end
push!(M,sum(MM))
end

Memoisation in OCaml and a Reference List

I am learning OCaml. I know that OCaml provides us with both imperative style of programming and functional programming.
I came across this code as part of my course to compute the n'th Fibonacci number in OCaml
let memoise f =
let table = ref []
in
let rec find tab n =
match tab with
| [] ->
let v = (f n)
in
table := (n, v) :: !table;
v
| (n', v) :: t ->
if n' = n then v else (find t n)
in
fun n -> find !table n
let fibonacci2 = memoise fibonacci1
Where the function fibonacci1 is implemented in the standard way as follows:
let rec fibonacci1 n =
match n with
| 0 | 1 -> 1
| _ -> (fibonacci1 (n - 1)) + (fibonacci1 (n - 2))
Now my question is that how are we achieving memoisation in fibonacci2. table has been defined inside the function fibonacci2 and thus, my logic dictates that after the function finishes computation, the list table should get lost and after each call the table will get built again and again.
I ran some a simple test where I called the function fibonacci 35 twice in the OCaml REPL and the second function call returned the answer significantly faster than the first call to the function (contrary to my expectations).
I though that this might be possible if declaring a variable using ref gives it a global scope by default.
So I tried this
let f y = let x = ref 5 in y;;
print_int !x;;
But this gave me an error saying that the value of x is unbounded.
Why does this behave this way?
The function memoise returns a value, call it f. (f happens to be a function). Part of that value is the table. Every time you call memoise you're going to get a different value (with a different table).
In the example, the returned value f is given the name fibonacci2. So, the thing named fibonacci2 has a table inside it that can be used by the function f.
There is no global scope by default, that would be a huge mess. At any rate, this is a question of lifetime not of scope. Lifetimes in OCaml last as long as an object can be reached somehow. In the case of the table, it can be reached through the returned function, and hence it lasts as long as the function does.
In your second example you are testing the scope (not the lifetime) of x, and indeed the scope of x is restricted to the subexpresssion of its let. (I.e., it is meaningful only in the expression y, where it's not used.) In the original code, all the uses of table are within its let, hence there's no problem.
Although references are a little tricky, the underlying semantics of OCaml come from lambda calculus, and are extremely clean. That's why it's such a delight to code in OCaml (IMHO).

D-like slices of immutable data in OCaml

Does OCaml have slices (like D slices of immutable data)? It seems like it would fit really nicely into the OCaml paradigm (you could avoid constantly having to reverse a list every time you want to do any kind of processing with tail recursion, because you can access/slice the list from both ends). Would it be difficult to implement?
As an example, if OCaml lists behaved like slices, I could say
let merge lhs rhs =
merge_helper lhs rhs []
let rec merge_helper lhs rhs res =
match lhs with
| [] -> res ^ rhs
| l_first :: l_rest ->
match rhs with
| [] -> res ^ lhs
| r_first :: r_rest ->
if l_first <= r_first then
merge_helper l_rest rhs (res ^ [l_first])
else
merge_helper lhs r_rest (res ^ [r_first])
Where lhs ^ rhs attempts to concatenate them by copying rhs into the space next to lhs (if available) and otherwise copies them into a new slot in memory at least twice as large as lhs.
EDIT: Perhaps I need to clarify
Concatenation such as let concatted = lhs ^ rhs is not a mutating operation. lhs will be the same as it was, and rhs will be the same as it was. concatted may or may not point to the same segment of memory as lhs (just with a larger length). The copying I was talking about is an "under-the-hood" operation. From the client's perspective all objects behave as if they were immutable and the construction lhs ^ rhs takes amortized O(|rhs|) time (amortized in the sense that if we keep on constructing longer slices by repeatedly concatenating things on the right, the number of internal re-allocations is small).
EDIT 2: Sorry, I was imagining that concatenating behaves like D appending. D doesn't do this because they also allow slices of mutable data, but in OCaml things default to immutable, so this wouldn't be a problem (at least, no more than it is for D lists).
I think you don't understand what lists are. You seem to consider that a list is just like a c++ vector (I don't know D's slices but from what I have found, it looks like a c++ vector) but with more restrictions.
It is not! A list is immutable, persistent and gives constant time cons (::) and it is impossible to achieve this with an array (even with a smart array that you call slice).
example of thing you can do with lists but not with arrays:
let l = [1; 2; 3; 4; 5]
let a = 0 :: l
let b = 1 :: l
the last two lines are constant time (no matter the size of l) and add constant space.

Resources