Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parentheses in Ocaml

Tags:

ocaml

I am evaluating a very simple piece of code in Ocaml toplevel:

let p5 () = print_int 5;;
p5 ();;

print_string "*************************";;

let p4 = print_int 4;;
p4;; 

And it returns:

val p5 : unit -> unit = <fun>
#   5- : unit = ()
#   *************************- : unit = ()
#   4val p4 : unit = ()
#   - : unit = ()

My questions are

  1. What does () mean in let p5 () = print_int 5;;?
  2. What do - and () mean in # 5- : unit = ()?
  3. Is p4 a function?
  4. Why is there a 4 in the beginning of # 4val p4 : unit = ()?
  5. It seems that () could be used in Ocaml code to hide side effect, could anyone show me an example?
like image 260
SoftTimur Avatar asked Oct 10 '11 10:10

SoftTimur


2 Answers

Here some answers:

  1. () is the unit type value. The unit type is a type with only one value. This is usually used to produce functions which either return nothing meaningful or take nothing meaningful. Remember, that in OCaml all functions alway have to return something and take some arguments, so the unit type is used to get around this limitation. Think of this similar to the void type in C, C++ or Java.
  2. There are two lines interleaved. The 5 is printed by the print_int function and not by the toplevel. The toplevel just returns - : unit = () without the 5. The toplevel is telling you that it did not create any new bindings - and that the last returned value is of type unit and has the value ().
  3. No. It does not take any arguments, so it is not a function.
  4. Again there are two lines interleaved. The 4 is printed by the print_int function. At this time, the toplevel is telling you, that it created a new binding p4, that this variable carries a value of type unit and that the stored value is ().
  5. No, () is not used to hide side effects. It is usually used to create functions, which have side effects, and thus need not take any kind of argument.
like image 98
LiKao Avatar answered Oct 11 '22 14:10

LiKao


LiKao has explained all the key points already, but I thought it might make more sense if you entered your definitions one line at a time, which would show which responses come from which inputs. Lines entered by the person start with #.

# let p5 () = print_int 5;;
val p5 : unit -> unit = <fun>

This defines p5 as a function that accepts values of type unit and returns values of type unit. There's only one value of type unit, which is written as (). So these are exactly the parentheses you are asking about (I think). Note that the () appearing in your definition is a pattern for the values accepted by the function. As a pattern, () matches itself (like all constants used as patterns).

# p5 ();;
5- : unit = ()

This is a little confusing. The 5 is written by your function p5. The rest is the response from the OCaml top-level. It's saying that the result of your expression is of type unit and has the value (). It makes sense, print_int is of type int -> unit.

# print_string "*************************";;
*************************- : unit = ()

There's a similar confusion here. The asterisks * are written by print_string. The rest shows the result, which again is of type unit with value ().

# let p4 = print_int 4;;
4val p4 : unit = ()

Same thing here. The 4 is written by print_int. The rest shows that the top level has defined a symbol named p4 whose type is unit and whose value is (). Again, this makes sense because print_int returns unit type and () is the only value of that type. You can tell from the type of p4 that it is not a function. Functions have an arrow (->) in the type. p4 is just a value of type unit.

# p4;;
- : unit = ()

Here you ask the top-level for the type and value of p4, and it tells you (again) that p4 is of type unit and has the value ().

like image 24
Jeffrey Scofield Avatar answered Oct 11 '22 14:10

Jeffrey Scofield