On Wed, Aug 19, 2015 at 9:52 AM, Hendrik Boom wrote: > > The way to make this explicit is to write > > let init flags = > (M.init (M.flag1 + M.flag2 + flags) (* flags is 'local', and is not > shadowed by a value in M *) > > THe code is one characte longer, and even the comment becomes smaller! > > The '+' operator is also from M, not just normal addition. And, instead of M, it might be "Sdl.Init". :) Local open has been fantastic for code hygene and clarity -- previously it was very common to define local module aliases (even though they weren't actual aliases at the time!): module S = Sdl.Init... and then prefixing everything with S, similar to your example. But this is ugly, still redundant, plus it adds cognitive indirection (alias). Often when I use a local open it's in an expression which uses mostly values from the opened module, with a few from local scope, very much like the example I gave. If it's not heavily from the external module, of course I only prefix the relevant identifiers rather than opening scope. I've always hated the following function-call sloppiness in several languages: Namespace::func( Namespace::arg1, Namespace::Enum::arg2, myArg ); I felt like the arguments should be implicitly open to the namespace of the called function. Then local-open in OCaml, particularly with the short syntax M.(), provided an elegant solution -- without need for anything implicit! I facepalmed that day. Module.(func arg1 Enum.arg2) myarg Fantabulous! Now the minor quibble to this otherwise luxurious syntax is that there is no way to make it clear when something really is local rather than coming from an opened scope -- and this arises when currying doesn't pan out as nice as the above, or more often: once binary operators are involved. But as I said, there has been the related (at least conceptually) thorn of the inability to specify the path of the current module. I'm hoping someone familiar with OCaml internals and style has a bright idea.