Immutable variables in OCaml - ocaml

I'm learning OCaml, and I'm a bit confused with the immutability of variables. According to the book I'm reading, variables are immutable. So far so good, but why on Earth can I do this:
let foo = 42
let foo = 4242
What am I missing??

I think the best way to explain is with an example. Consider this code (executed in the OCaml REPL):
# let foo = 42;;
val foo : int = 42
# let return_foo () = foo;;
val return_foo : unit -> int = <fun>
# let foo = 24;;
val foo : int = 24
# return_foo ();;
- : int = 42
The above code does the following:
Binds 42 to the name foo.
Creates a function return_foo () that returns the value bound to foo.
Binds 24 to the name foo (which hides the previous binding of foo).
Calls the return_foo () function, which returns 42.
Compare this with the behaviour of a mutable value (created using ref in OCaml):
# let foo = ref 42;;
val foo : int ref = {contents = 42}
# let return_foo () = !foo;;
val return_foo : unit -> int = <fun>
# foo := 24;;
- : unit = ()
# return_foo ();;
- : int = 24
which:
Creates a mutable reference containing 42 and binds it to the name foo.
Creates a function return_foo () that returns the value stored in the reference bound to foo.
Stores 24 in the reference bound to foo.
Calls the return_foo () function, which returns 24.

The name foo is first bound to an immutable value 42 and later it is rebound to another immutable value 4242. You can even bind the same name to variables of different types. In OCaml we are talking not about mutability of a variable, but about a mutability of a value. For example, if you bind foo to an array of values, this would be the same name, but bound to a mutable data, so that the value of a variable can change in time. Finally, each new binding just hides the previous one, so the original foo is still bound to 42, but it is invisible and will garbage collected.
Maybe a little example will clarify the idea:
let example () =
let foo = 42 in (* 1 *)
let foo = 4242 in (* 2 *)
let foo = [|42|] in (* 3 *)
foo.(0) <- 56 (* 4 *)
It might be easier to have the following mental model:
(*1*) +--------+
+----> | 42 |
+------------+ | +--------+
| +----+
| foo +----+ +--------+
| | +----> | 4242 |
+---------+--+ (*2*) +--------+
|
| (*3*) +--------+
+------------> |[| 42 |]|
(*4*) +--------+
On lines 1 and 2 we just bind a variable foo to two different values. On line 3 we bind it to an array that contains one element. On line 4, we change the value, and foo is still bound to the same value, but the value contains different datum.
I hope I didn't confuse you even more ;)

The usual form of let is the let ... in expression, where you define a variable binding, which only exists in the inside of the body of the let. The body of the let is a new scope.
let x = 42 in (* body here *)
Here the "body" of the let is a new scope that is different from the one outside, with all the variables from the outside with an additional local variable x that is only defined in the body of this let.
Now you are talking about lets at the top level of the file. These look a little different syntactically (there is no in), but really they are the same, with the "body" being the rest of the file. So here you can think of the rest of the file after the let as a new scope, with x being a local variable of this scope. So your code is equivalent to this:
let foo = 42 in (
let foo = 4242 in (
(* rest of file *)
)
)
Here your inner let binds a local variable that has the same name as a variable that already exists in the outer scope. That doesn't matter. You are binding a new variable in an inner scope. If it happens to have the same name as a variable in an outer scope, then code in the inner scope referencing that name will refer to the innermost binding. The two variables, however, are completely independent.
In a C-like language, it would be something like this:
{
const int foo = 42;
{
const int foo = 4242;
// rest of code here
}
}
See? There is no assignment to any variables here.

Related

How to Define Something that Acts as a Dictionary of Unique Functions in F#?

It is my understanding that a Dictionary's elements must all be the same (ie: unit -> unit)
I need a way to add functions to an object, similar to a Dictionary, but my problem is that the functions have different Types. The only thing I can know for sure is that added functions will always follow a pattern of int -> 'T where 'T could be any Type. All functions in the object could be made to inherit from a shared type if needed. Here is a non-functioning example of how it would be used.
let myFunctions = Dictionary<int,int -> unit>()
let exampleFunction0 (x : int) : int = x + 1
let exampleFunction1 (x : int) : byte = (byte)x
let exampleFunction2 (x : int) : string[] = Array.create<string> 1 "test"
myFunctions.Add(0, exampleFunction0)
myFunctions.Add(1, exampleFunction1)
myFunctions.Add(2, exampleFunction2)
let randomNumber = System.Random().Next(3)
let result x = myFunctions.Item(randomNumber) x
It is important to note that which one of the functions that gets called is random and I cannot know it. The purpose of the dictionary is to hold the functions that will be called randomly. As in the examples, the results are not the same as I need the results to be different for each function. x will always be the same, but the result of the function will not.
The code will be in a library to be reused, so functions may be added that I will never see.
You need to unify the output types to make this work.
If all the types are known you should use a Discriminated Union.
type ReturnValues =
| Case0 of int
| Case1 of byte
| Case2 of string[]
let myFunctions = Dictionary<int,int -> ReturnValues>()
let exampleFunction0 (x : int) = x + 1 |> Case0
let exampleFunction1 (x : int) = (byte)x |> Case1
let exampleFunction2 (x : int) = Array.create<string> 1 "test" |> Case2
myFunctions.Add(0, exampleFunction0)
myFunctions.Add(1, exampleFunction1)
myFunctions.Add(2, exampleFunction2)
let randomNumber = System.Random().Next(3)
let result x : ReturnValues = myFunctions.Item(randomNumber) x
If you don't know all the types you can make all the return types obj (Dictionary<int,int -> obj>) using the box function or you can make all the return types implement a common interface.
What has ultimately solved the problem for me is to package together the Type and Object. This package is what the functions that will be added to the dictionary must return. This way there is a standard way for new types to be added after compilation.
open System.Collections.Generic
open System
// a package that can hold an object and its type
type package(x, y) =
member this.x : Type = x
member this.y : Object = y
//empty class for testing
type testClass() = class end
//custom types for testing
type fiy(x) =
member this.Value : string = x
type foe(x) =
member this.Value : testClass = x
//functions for testing
let func0 (x: int) : package = package(typeof<int>, x)
let func1 (x: int) : package = package(typeof<fiy>, fiy("potato"))
let func2 (x: int) : package = package(typeof<foe>, foe(testClass()))
let myFunctions = Dictionary<int, (int -> package)>()
//example use of adding a function
myFunctions.Add(0, (func0))
myFunctions.Add(1, (func1))
myFunctions.Add(2, (func2))
//pick a random number to test with; as we will have no idea which function will be ran
let randomNumber = System.Random().Next(3)
let pickedFunction x : package = (myFunctions.Item(randomNumber) x)
let ranFunction = pickedFunction 5 //just some filler number to test with
printfn "The type of the ranFunction is: %s" (ranFunction.x.ToString())

How to have function returned value in a SML record

I am new to SML, trying to explore SML record and types, specifically how to have function inside a record.
For example, I created below type-
type foo={
var1:int,
f1: int -> int // want to have result of function f1 here
};
Now if I declare record of type 'foo'-
val rec1 = { var1= 10, ....}
I am not getting how to populate the 2nd parameter in the record. f1(10) is giving error.Also, can we declare and define the function inside 'type' like below -
type foo ={
var1:int,
f1 (x)=x+x
};
Please share your opinion.
You need to use a function expression:
val r = {var1 = 10, f = fn x => x}
No, you cannot define the value of a record field in a type definition. But you can define a little helper function as a "constructor":
fun new_foo i = {var1 = i, f = fn x => x+x}

OCaml - mutable fields

I have a question:
What is it mutable field ?
Is it connected with reference ?
If I can create mutable "without" creating record
Thanks in advcane!
Actually, references are implemented in terms of mutable fields:
a reference is just a record with a single (mutable) field named
contents, as you can see in your toplevel:
# let x = ref 1;;
val x : int ref = {contents = 1}
# x.contents;;
- : int = 1
# x.contents <- 2;;
- : unit = ()
# !x;;
- : int = 2
The main way to get mutable fields is to use records, and it is the
way you should prefer. Objects have mutable instance variables. You
can also get the equivalent of references by using one-element arrays.

inserting EQUALOP error in SML

I am trying to swap elements in a list in ML. My swap function returns the error inserting EQUALOP.
fun swap(n:int, i:int, deck:card list) =
local
val card1_removed = nth(deck,i)
val card2_removed = nth(deck,n)
in
val deck = remove(deck,i)
val deck = remove(deck,n)
val deck = insert_at(deck,n,card1_removed)
val deck = insert_at(deck,i,card2_removed)
print_cards(deck);
end;
Any suggestions?
There are a few problems with your code.
First off you cant have a local declaration inside a function definition like that. The body of a function must be an expression, and local ... in .. end is a declaration. In this case you have to use let ... in .. end, which is an expression.
Note that you can't have value declarations in the in ... end part of a let-expression though. Here you will have to move all the value declarations up in the let ... in part.
To be a bit more clear the form of let and local is:
<atexp> ::= let <dec> in <exp_1> ; ... ; <exp_n> end
<dec> ::= local <dec_1> in <dec_2> end
Thus, normally local is used like this
local
fun foo ...
val ....
in
fun swap ...
end
where let is used like this
fun swap ...
let
val ...
in
..
end

Ocaml - Forward Declaration (Classes)

I need to have two classes refering to each other. Is there any way in Ocaml to make Forward Declaration of one of them?
(I don't think it's possible as with easier stuff with word and).
Or maybe it is possible, but different way than how i tried?
Ocaml doesn't have anything like forward declarations (i.e. a promise that something will be defined eventually), but it has recursive definitions (i.e. a block of things that are declared and then immediately defined in terms of each other). Recursive definitions are possible between expressions, types, classes, and modules (and more); mutually recursive modules allow mixed sets of objects to be defined recursively.
You can solve your problem using a recursive definition with the keyword and:
class foo(x : bar) = object
method f () = x#h ()
method g () = 0
end
and bar(x : foo) = object
method h () = x#g()
end
Or you could use parameterized classes. Following the previous example you have:
class ['bar] foo (x : 'bar) =
object
method f () = x#h ()
method g () = 0
end
class ['foo] bar (x : 'foo) =
object
method h () = x#g()
end
The inferred interface is:
class ['a] foo : 'a ->
object
constraint 'a = < h : unit -> 'b; .. >
method f : unit -> 'b
method g : unit -> int
end
class ['a] bar : 'a ->
object
constraint 'a = < g : unit -> 'b; .. >
method h : unit -> 'b
end