Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Guarantying assignment to a function's return value in OCaml

Coming to OCaml from Lisp, I find myself very confused about when functions return and when they don't. I miss my magic Quote! Thankfully, most of the time, OCaml appears to automagicly know when I want a function evaluated and when I don't. However, I frequently find myself trying to assign the return value of a function in a let expression, like the following.

let start = Sys.time in
(*
 * do something here
 *)
 ;
let ending = Sys.time in
Printf.printf "did something in %f seconds\n" (ending -. start)

but then ocamlc complains

Error: This Expression has type unit -> float
       but an expression was expected of type float

Telling me that start and end are bound to Sys.time, not the return value of Sys.time.

Is this behavior I'm trying to get not OCamly? Do I want to be doing things another way? Am I just missing something completely obvious?

like image 414
Eli Avatar asked Sep 12 '10 23:09

Eli


2 Answers

A function is evaluated when you apply it to an argument. I.e. when you do f, f never gets evaluated. When you do f x, f always gets evaluated. There's nothing magical about it.

As you correctly pointed out, Sys.time is a function (of type unit -> float) and let start = Sys.time just assigns that function to start.

To get the behavior you want simply do let start = Sys.time (), which applies the function Sys.time to the argument () (which is the only value of type unit).

like image 91
sepp2k Avatar answered Oct 21 '22 04:10

sepp2k


You cannot call a function just by writing its name. If you just write a function's name, you're returning the function itself, not its return value. That error is telling you that the function takes a unit argument — i.e., you should write Sys.time () to actually apply the function and get the resulting float value.

like image 30
Chuck Avatar answered Oct 21 '22 03:10

Chuck