function binarySearch(arr, target, opt_compareFn) {
  return binarySearch_(
      arr, opt_compareFn || defaultCompare, false /* isEvaluator */, target);
}
Searches the specified array for the specified target using the binary
search algorithm.  If no opt_compareFn is specified, elements are compared
using <code>defaultCompare</code>, which compares the elements
using the built in < and > operators.  This will produce the expected
behavior for homogeneous arrays of String(s) and Number(s). The array
specified <b>must</b> be sorted in ascending order (as defined by the
comparison function).  If the array is not sorted, results are undefined.
If the array contains multiple instances of the specified target value, the
left-most instance will be found.

Runtime: O(log n)

@param {IArrayLike<VALUE>} arr The array to be searched.
@param {TARGET} target The sought value.
@param {function(TARGET, VALUE): number=} opt_compareFn Optional comparison
    function by which the array is ordered. Should take 2 arguments to
    compare, the target value and an element from your array, and return a
    negative number, zero, or a positive number depending on whether the
    first argument is less than, equal to, or greater than the second.
@return {number} Lowest index of the target value if found, otherwise
    (-(insertion point) - 1). The insertion point is where the value should
    be inserted into arr to preserve the sorted property.  Return value >= 0
    iff target is found.
@template TARGET, VALUE