Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between let-bindings and references in OCaml?

The OCaml tutorials say that references are "real variables" which you can assign to and change throughout a program. Let-bindings do not serve the same purpose. In this link it says that when a name is set by a let-binding you cannot "...reassign it to point to a different widget." I understand that the references are actually stored in memory and let-bindings are not but i don't understand what they are saying about the assignment.

Playing around in an Ocaml interactive session, it seems like let-bindings and references do the same thing with some differences in the syntax. If I set a variable name to some integer value using a let-binding that name will return that value until I disestablish it or reset the name to a different integer, which the let-binding will allow. This is true for ints, floats and strings but have not tried other types. What am i missing?

# let let_var = 2;;
val let_var : int = 2
# let_var;;
- : int = 2
# let let_var = 3;;
val let_var : int = 3
# let_var;;
- : int = 3
like image 244
andrewhunter Avatar asked Jul 09 '15 03:07

andrewhunter


People also ask

What is binding in OCaml?

In OCaml, a name cannot exist without a value. Variables are called bindings—names bound to values. The same name can later be bound to a different value, but the value itself will not change. Bindings are created with the let keyword.

What does REF do in OCaml?

ref's (references) allow you to make any type of value mutable (sort of). (You can't create an uninitialized reference: this helps prevent bugs.) A ref is a first-class value -- you can store it in a data structure, pass it to a function, and return it from a function.

What does -> mean in OCaml?

The way -> is defined, a function always takes one argument and returns only one element. A function with multiple parameters can be translated into a sequence of unary functions.

What is () in OCaml?

This is a way to indicate there is no value for an argument. It's necessary to do this in ML because all functions are unary. You can't have a function with zero arguments, so instead you pass an argument containing no information, which is () .


2 Answers

The best way to look at things is that a let binding is a way of giving a permanent name to something. Since OCaml's scoping rules allow you to re-use names, it's possible to give the same name to something else in an inner context. But the first name is still there in some sense, and is still associated with its permanent value.

Here's a session that might help illustrate this:

$ ocaml
        OCaml version 4.02.1

# let v = 12;;
val v : int = 12
# let g x = v + x;;
val g : int -> int = <fun>
# g 10;;
- : int = 22
# let v = 200;;
val v : int = 200
# g 10;;
- : int = 22
#

In this session there are two different let bindings with the same name v. The function g uses the first one. If you create a new binding named v, this doesn't change anything about g.

On the other hand, a reference is a value. It's not a name at all, it's a kind of value that is mutable; i.e., it holds another value that can be changed. The following session might help illustrate this:

# let myref = ref 12;;
val myref : int ref = {contents = 12}
# let h x = !myref + x;;
val h : int -> int = <fun>
# h 10;;
- : int = 22
# myref := 200;;
- : unit = ()
# h 10;;
- : int = 210

Here myref is a let-bound variable referring (permanently) to a value that is a reference. Initially the reference holds the value 12. But the value can be changed. The function h uses whatever is the current value stored in the reference. But note (again) that myref hasn't changed. It still is (permanently) associated with the same reference.

like image 126
Jeffrey Scofield Avatar answered Sep 26 '22 05:09

Jeffrey Scofield


The way I look at it, let defines a variable, and all variables in OCaml are unmodifiable -- there is simply no syntax to assign to a variable.

Some variables are pointers to composite data structures, and some data structures are mutable (including arrays, strings, and records/objects with mutable fields). A "reference", a mutable cell, is the simplest mutable data structure and there are operators already provided in Pervasives in the standard library for working with it; but it's otherwise no different from other mutable data structures.

For an analogy, it's like if you were in Java, and all variables are always final. And you have a data structure Ref<T> which you can allocate with new Ref<Integer>(...) to get a reference to this object, and you can access its single piece of data with .get(), .set(), etc. and you can assign the reference to this data structure to other variables so you can share the changes to this data structure across references. The exact same thing is happening with ref in OCaml -- you allocate it with ref ... to get the reference, and then access its single piece of data with ! and <-, and you can assign the reference to other variables to share a view to the same data structure across references.

like image 30
newacct Avatar answered Sep 24 '22 05:09

newacct