So I'm pretty surprised by the semantics of [slice]:
utop # String.slice "foo" 1 1;;
- : string = ""
utop # String.slice "foo" 2 2;;
- : string = ""
utop # String.slice "foo" 0 0;;
- : string = "foo"
This feels like an API error which is likely to lead to real bugs. "0" looks like a poor choice of sentinel value, as it violates the reasonable expectation that [String.slice s n n] generates the empty string for all [n].
Python's slicing operator doesn't use sentinel values, and instead makes the start and end parameters optional. Inspired by that convention, I've been using the following workaround:
let str_slice ?(start : int option) ?(stop : int option) (s : string)
: string =
(* Core_string.normalize *)
let norm s i = Core.Ordered_collection_common.normalize
~length_fun:String.length s i
in
let real_start =
match start with
| Some x -> norm s x
| None -> 0
in
let real_stop =
match stop with
| Some x -> norm s x
| None -> String.length s
in
String.sub s real_start (real_stop - real_start)
Any chance of getting a change here? I don't like having to be mistrustful of standard library functions.
Paul