From Real World Ocaml, page 24 (see https://realworldocaml.org/v1/en/html/a-guided-tour.html#for-and-while-loops). The code is:
# let find_first_negative_entry array =
let pos = ref 0 in
while !pos < Array.length array && array.(!pos) >= 0 do
pos := !pos + 1
done;
if !pos = Array.length array then None else Some !pos
;;
val find_first_negative_entry : int array -> int option = <fun>
# find_first_negative_entry [|1;2;0;3|];;
- : int option = None
# find_first_negative_entry [|1;-2;0;3|];;
- : int option = Some 1
and
# let find_first_negative_entry array =
let pos = ref 0 in
while
let pos_is_good = !pos < Array.length array in
let element_is_non_negative = array.(!pos) >= 0 in
pos_is_good && element_is_non_negative
do
pos := !pos + 1
done;
if !pos = Array.length array then None else Some !pos
;;
val find_first_negative_entry : int array -> int option = <fun>
# find_first_negative_entry [|1;2;0;3|];;
Exception: (Invalid_argument "index out of bounds").
The authors claimed that:
As a side note, the preceding code takes advantage of the fact that &&, OCaml's And operator, short-circuits. In particular, in an expression of the form expr1 && expr2, expr2 will only be evaluated if expr1 evaluated to true. Were it not for that, then the preceding function would result in an out-of-bounds error. Indeed, we can trigger that out-of-bounds error by rewriting the function to avoid the short-circuiting:"
But I still do not really understand why the first code works fine, and the second get the exception. I complied and both function behave as expected. But I am very puzzled why the second function does not work, since it used the && command as well, and it handled no negative entry with None exception as well.
It is the order of evaluation. In the first function Term1 && Term2
allows &&
short circuit behavior to protect us from Term2. In the second example the let bindings are always evaluated before the test occurs. Therefore there is no protection from Term2's bad behavior.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments