# module X = struct
type t = {mutable i : int}
type s = {mutable i2 : t}
let x = {i2 = {i = 0}}
end;;
module X :
sig
type t = { mutable i : int; }
type s = { mutable i2 : t; }
val x : s
end
# X.x.X.i2.X.i <- 1;;
- : unit = ()
# X.x.X.i2.X.i <- X.x.X.i2.X.i + 1;;
- : unit = ()
# X.x.X.i2.X.i <- X.(x.i2.i) + 1;;
- : unit = ()
# X.(x.i2.i) <- X.(x.i2.i) + 1;;
Error: Syntax error
It seems the local open can be used for values, but not for the left-hand-side of a <- expression. Is this expected?
Before I report this as a bug or feature request, can anyone spot a reason why it couldn’t be added? Some grammatical ambiguity?
The left arrow is a bit complicated to parse. It has different meanings depending on what is on the left-hand side:
expr.label <- expr : record update
ident <- expr : instance variable update
expr.(expr) <- expr : array update
There are variants on the array update (for bytes, for bigarrays, as well as custom operators), but the key is that at parsing time it must be known in which category the left-hand side sits.
In your case, X.(x.i2).i would work, as well as X.(x.i2).X.i, but X.(...) doesn’t fit the required pattern for a record update.
It might be possible to extend the parser to support local opens on the left-hand side, but I suspect it is going to be a bit awkward, as you need to translate Mod.(expr.field) on the left-hand side into something like Mod.(expr).(let open Mod in field), with the latter part not currently supported in the OCaml AST. You could also generate Mod.(expr).M.field but this has a different meaning and is likely not what you want.