Conversation
|
I like this idea. Many of my modules only have a very small, or empty, interface. |
What's their rationale ?
What's the effect on build and documentation systems ? E.g. an Personally I tend to dislike the "let's have at least two or three different ways of acheiving the same goal" proposals and don't mind empty or small |
The document I've been able to read suggests this proposal without giving an explicit rationale in terms of security. I guess a reason is that preserving abstraction is good in general (and also for security), and making it less invasive to add (even empty) signatures will encourage users to do so; I could also try to argue that being able to detect dead code is also good for security (detects possible bugs), since the study also encourages the use of dead code detection tools. (But I doubt the authors did the connection between the two.)
Nothing is changed. You could even apply an extra .mli on top of the inline signature. But codoc could certainly decide to read the .cmt file when there is no .mli in order to extract the typedtree for the inline signature. |
|
I tend to agree with Daniel here. I'm not excited by having yet another way On Fri, Jul 17, 2015, 8:16 AM alainfrisch [email protected] wrote:
|
|
Same here, not convinced. What I would like, however, is the ability to put function signatures before an implementation in order to avoid the type constraints. val f : t1 -> t2 -> t3
let f x y z = ...instead of let f (x : t1) (y : t2) (z : t3) = ...That would be very helpful in the context of gadts in particular .... |
|
On Fri, 17 Jul 2015 05:16:04 -0700, alainfrisch wrote:
Wouldn't a warning about missing signatures be more effective in achieving these goals? |
|
On Fri, 17 Jul 2015 06:03:33 -0700, Gabriel Radanne wrote:
But you can write which is not too far from what you want. |
The place we use this feature at LexiFi is for "plugin" modules. Most of them have empty interfaces, and just being able to write "sig end" at the beginning gives a quick way of detecting unused declarations. Moreover, we expose an IDE to end-users, and forcing them to double the number of files (half of them being almost empty) would not be well perceived. This is so true so that, in order the simplify the IDE's interface (and its embedded build manager), it only manages .ml files (not .mli); so that for those end-users, each plugin is made of a single file. |
|
This could also be useful for something like ocamlscript as it would allow you to add |
|
2015-07-17 15:08 GMT+01:00 Hezekiah M. Carty [email protected]:
Alternatively, given the context ocamlscript (and lexify's |
So then why even bother these end-users into writing an empty |
|
On Fri, 17 Jul 2015 07:09:40 -0700, Thomas Refis wrote:
IMHO this is cleaner but would need to be turned on by a compiler flag to be backward compatible. |
Well, sometimes the signature is not empty (plugins can depend on each |
|
After all these years, I'm still keen on the idea that the signature (= the user's view) goes in a .mli file distinct from the .ml implementation file. I know other languages do it differently, with a single source file and visibility modifiers, but I still find the 2-file approach healthier. For one thing, the .mli is the natural place to put user documentation that is clearly separate from implementation comments. Concerning the LaFoSec study, yes, for high-assurance software it makes sense to have an explicit interface for every source file so that internal definitions don't leak out unintentionally. But it is trivial to check for existence of .mli interfaces in a code review tool. I don't see a clear case for changing the language here. |
|
I agree that a separate file is good for many reasons, but it also comes with drawbacks, such as higher maintenance costs. One thing that would be nice to have is an attribute that hides a toplevel expression when an mli is implicitly generated -- something like [@no_export]. Additionally, a toplevel [@no_export] would make the whole file local by default, which could be undone piecemeal by [@export] on expressions. All of these attributes would be ignored if an mli file was provided, or perhaps could generate warnings/errors if the attributes mismatched the mli content. |
|
Regarding the "high maintenance cost" of separate interface files: shouldn't this be handled by the IDE tooling? The tooling approach works great for modern industrial languages. Can't see why it won't work for OCaml. No need to complicate the language itself. |
|
I agree with @xavierleroy . However, I would be in favour of a warning when the .mli file is missing, if a certain compiler flag were provided. |
|
I like @bluddy 's idea, having
|
|
We discussed this PR at the developer meeting two days ago and the consensus is to reject this PR. On the other hand, it would be a good idea to have a flag to force the compiler to raise an error when the |
Delete lots of signal-handling stuff
It is sometimes convenient to specify the external interface of a compilation unit directly in the .ml file. In particular, for "plugin" modules which are supposed to be dynlinked independently, the external interface is empty, and it can be inconvenient having to specify an empty .mli file. Benefits of having an explicit external interface even in such cases are clear: enable unused-stuff warnings to be triggered; prevent accidental use of internal components by other modules.
One of the recommendations of the LaFoSec study (about the security aspects of OCaml) is precisely to allowing defining the interface of a module directly in the .ml file. This pull request implements this recommendation by allowing an initial
sig ... enddeclaration at the top of implementation files. This is currently done purely as syntactic sugar, mapping this to:If one agrees on the benefit of the proposal and on the syntax, one could discuss whether we should represent the new form explicitly in the Parsetree and/or compile the construction specifically (to avoid creating the included structure).
FWIW, this extension has been in use at LexiFi for several years (precisely to restrict the interface of plugins, which is often empty or very small).