Hacker News new | past | comments | ask | show | jobs | submit login

> Right but in practice most OCaml code does not have explicit types.

Most OCaml code use .mli which does have types. This is the recommended practice but I noticed a lot of beginners coming from other languages are reluctant to use them (because of duplication). It's a simple idea but I think it's a strong point of OCaml and it makes easier to program "in the large" than Haskell for instance.




But .mli files do not help with the "no types in the source code" problém. You need LSP (Merlin) to "see" the types anyway. Only adding the signature in the samé (.ml) file helps against that problém.

And I did not experience any advantage of separate signature files so far, but I also haven't written anything large in OCaml (>100 kLOC).


> But .mli files do not help with the "no types in the source code" problém

It partially helps since it forces you to have types where they matters most: exported functions

> And I did not experience any advantage of separate signature files so far,

100kLoc is already quite big! I'm starting to think I'm an outlier since a lot of people don't see the benefits :)

For me, it helps because I really don't want to see the implementation when I use an API. If I need to look at the implementation, it means the interface isn't well specified. All I need should be in the interface: types, docs, (abstract) types. And no more.

Typically, an .ml file will have more than what is exported, types won't be abstract but will have a concrete implementation, and type signatures may be missing. How would it feels like to use list if only https://github.com/ocaml/ocaml/blob/trunk/stdlib/list.ml was available, instead of https://github.com/ocaml/ocaml/blob/trunk/stdlib/list.mli? and that's not the most compelling example since it's a simple module where the main type isn't abstract. Generally speaking, giving up mli means giving up on encapsulation which is one of the primary tools to deal with large programs.

Haskell forces you to say what is exported from a module, but the module user can only see the names. To see the signatures, you need to rely on generated doc or look it up on the code.

Arguably, since OCaml has includes, it suffers from the same problem, your ".mli" may have tons of include and it becomes harder to see what's exported without an external tool


> It partially helps since it forces you to have types where they matters most: exported functions

But the problém the OP has is not knowing the types when reading the source (in the .ml file).

> How would it feels like to use list if only https://github.com/ocaml/ocaml/blob/trunk/stdlib/list.ml was available,

If the signature where in the source file (which you can do in OCaml too), there would be no problem - which is what all the other (for some definition of "other") languages except C and C++ (even Fortran) do.

No, really, I can't see a single advantage of separate .mli files at all. The real problém is that the documentation is often worse too, as the .mli is autogenerated and documented afterwards - and now changes made later in the sources need to be documented in the mli too, so anything that doesn't change the type often gets lost. The same happens in C and C++ with header files.


How do you do encapsulation without an mli? can you hide the type implementation to the module user? can you ensure the exported functions (which are all of them without an mli) maintain your type invariant?

> the real problém is that the documentation is often worse too, as the .mli is autogenerated and documented afterwards

Of course, that would defeat the purpose of having interfaces and is incredibly bad practice. People do that when they try to fix an already broken codebase. It's actually pretty ironic that people who care about type safety (which I is why they use OCaml in the first place) don't value (or understand) things like encapsulation.


I find Rust is really effective in this regard. From my understanding of the capabilities of mli files, Rust's visibility modifiers are even more powerful in terms of effectively hiding implementation details and maintaining invariants, but they're all written inline in the source code (with the `pub` keyword).

I agree that the encapsulation capabilities of mli files are great, but I don't see why they need to be written in a separate file (apart from the obvious reason: that's how OCaml does it, and you can't just change a language's design just because you don't like one bit of it!)


> How do you do encapsulation without an mli?

In OCaml you can't. If I could I wouldn't care about interface files, because I wouldn't need them.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: