title: What is the essential difference between the two functions to find the first negative entry?
body: <p>From <em>Real World Ocaml</em>, page 24 (see <a href="https://realworldocaml.org/v1/en/html/a-guided-tour.html#for-and-while-loops" rel="nofollow">https://realworldocaml.org/v1/en/html/a-guided-tour.html#for-and-while-loops</a>). The code is:</p>
  
  <pre><code># let find_first_negative_entry array =
       let pos = ref 0 in
       while !pos &lt; Array.length array &amp;&amp; array.(!pos) &gt;= 0 do
         pos := !pos + 1
       done;
       if !pos = Array.length array then None else Some !pos
    ;;
  val find_first_negative_entry : int array -&gt; int option = &lt;fun&gt;
  # find_first_negative_entry [|1;2;0;3|];;
  - : int option = None
  # find_first_negative_entry [|1;-2;0;3|];;
  - : int option = Some 1 
  </code></pre>
  
  <p>and </p>
  
  <pre><code># let find_first_negative_entry array =
       let pos = ref 0 in
       while
         let pos_is_good = !pos &lt; Array.length array in
         let element_is_non_negative = array.(!pos) &gt;= 0 in
         pos_is_good &amp;&amp; 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 -&gt; int option = &lt;fun&gt;
  # find_first_negative_entry [|1;2;0;3|];;
  Exception: (Invalid_argument "index out of bounds").
  </code></pre>
  
  <p>The authors claimed that:</p>
  
  <blockquote>
    <p>As a side note, the preceding code takes advantage of the fact that
    &amp;&amp;, OCaml's And operator, short-circuits. In particular, in an
    expression of the form expr1 &amp;&amp; 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:"</p>
  </blockquote>
  
  <p>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 &amp;&amp; command as well, and it handled no negative entry with None exception as well. </p>