Why is it that array and string indexing uses subtly different syntax?
E.g.
let _: int = [|1;2;3|].(0)
let _: char = "123".[0]
I (and others) find this to be both weird and confusing.
For exactly the same reason that Ocaml use +
for integer additions and +.
for float additions: OCaml foregoes ad-hoc polymorphism/function overloading and indexing operators are currently considered as a form of functions in OCaml and are thus subject to the same restrictions as functions.
More precisely, indexing operators are currently a very shallow syntax sugar: the parser rewrites x.(n)
to Array.get x n
and x.(n) <- y
to Array.set x n y
(or Array.unsafe_get
and Array.unsafe_set
if compiled with the -unsafe
option). Similarly,
s.[n]
is rewritten to String.get s n
and s.[n]<-x
becomes String.set s n x
.
This means that it is possible to define your own indexing operator by defining a new Array
module. For instance, the following ill-advised
trick will make array indices start at 1
:
module Array = struct
include Array
let get a n = get a (n-1)
let unsafe_get a n
end
;; [|1|].(1)
Note that there is no guarantee that this kind of hackish code will work in the future. If you want to define your own indexing operator, it is possible starting with OCaml ≥ 4.06 to define extended indexing operator by inserting at least one (operator) character between the dot .
and the left bracket (either (
, [
, {
).
let (.?()) dict key = Dict.find_opt dict key
If you, somehow, wish for less indexing operators, there is a proposition to make indexing for array-like data types a primitive operation and not a function call. This would allow to use type-directed disambiguation like it is already done for record fields. This means that both
let first (s:string) = s.(0)
let first (a: _ array) = a.(0)
would be possible since the type-checker will use type information to resolve which primitive operation should be used.
However, this proposal is still a work in progress (see https://github.com/ocaml/ocaml/pull/616 ), so for now it is required to distinguish between string and generic array indexing by the syntax.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With