New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A way to avoid automatic export of declaration in inferred signatures #5764
Comments
Comment author: @hcarty A more backwards compatible and perhaps less shocking approach could be to have 'ocamlc -i foo.ml' not include these values. This could be the default or something which could be set through a command line flag. |
Comment author: @bobzhang hcarty: the problem is that sometimes you don't want to write .mli file, and simply want to hide functions beginning with '
I hope that the signature inferred for functor M hide those functions beginning with ' |
Comment author: @damiendoligez For the record, I don't like this idea, it looks too much like an ad-hoc hack. |
Comment author: @bobzhang Why do you think it's an hack? this is just similar to add an underscore _ to remove the warnings, not theoretical interest, but very beneficial to the ocaml programmers. let private f = blabla? |
Comment author: meyer I don't like the idea either. Useful thing to do is to have an update mode for mli file. The compiler will just try to update (equiped with command line option) changed entries in mli file. |
Comment author: meyer I raised #5777 |
Comment author: @bobzhang in practice, you never want to read .mli file, the output is too large for generated code. can you explain a bit why you don't like the idea? |
Comment author: meyer mli files are used to expose the selected interface from the ml files and not other way round. If we start marking functions or types inside ml file to make the generated mli files the result will be the same not generating mli files in the first place. More over people will start abusing underscores in the code, and the underscored functions in my taste don't look very appealing. Reading mli file is fine, it's not needed to hbe type checked anymore, more over the ml files are usually bigger than mli files, especially in case when we use module types. In the case of the updating the mli file when is needed actually the file will be smaller because the modules that's been not changed will have module type. |
Comment author: @gasche A natural solution to your use-case would be to have the extension also generate the .mli file. However, I'm not sure that can be done conveniently (in my experience camlp4 is good at filtering/transforming a given file, but not that convenient for spitting out other files on the side; still the Ocsigen people do that iirc.), and it could be challenging to do compositionally. Maybe you could, in the .ml file, generate a module along with its interface, and then include it? Instead of generating:
you would generate
|
Comment author: @bobzhang yes, I know this can be 80% done in p4, but given the fact that just tens of lines patches in the compiler can solve the problem once and for all, it's not worth the complexity to use p4. Any feature can be abused, i.e, Obj.magic, personally, I can not buy meyer's argument. |
Comment author: lavi If I sometimes would like such kind of hiding expressed in ml files, I do not think that the name of a value should impact its visibility. So a cleaner solution would be e.g. to reuse private keyword: private let x = ... and the same for type, class, module... |
Comment author: @bobzhang yes, as I said |
Comment author: turpin I prefer "private let", because then you may also add "private type", "private module"... Also, if this was added to the language, allowing this in any structure (not just toplevel modules) would be less ad hoc. |
Comment author: berenger I think, by default everything is private. Hence the export or public keyword. I don't like so much __ because it's some code. |
Comment author: @bobzhang berenger, that will break all existing code, definitely not we want. private let module = struct |
Comment author: berenger I did not know about this private keyword, I'll study its use. |
Comment author: @alainfrisch Hongbo: what would be the type of the following structure? struct |
Comment author: turpin Error: type construcor t escapes its scope This problem seems similar to the following: let _ = |
Comment author: @bobzhang For private let and private module, remove its corresponding signature IMO, the output should be This will not change the typing rules, just add a filter after type checking. |
Comment author: @alainfrisch If you remove submodules, you can break well-formedness of type. How do you deal with: private module X = struct type t = A | B end ? |
Comment author: turpin The same "escapes its scope" sort of errors seems reasonable. I also have encountered other messages like "... cannot be eliminated from the signature", but I don't remember in which cases. I don't see any strong theoretical issue, and I believe the compiler already addresses similar problems for existing constructs. |
Comment author: @bobzhang As I said, any signature involves a private module type will result in a compilation error. If a module M is private, then any type declaration involves M will result in an error. private module X = struct type t = A | B end |
Comment author: @alainfrisch While modifying the Bisect instrumenter, we had introduced a bug which would have easily been avoided with the required feature. The modified instrumenter added a global value declaration at the top of the compilation unit, to be used at many places in the unit. The resulting code looks like: ============================================= ....
============================================= The __bisect_table identifier ends up in signature inferred for units without an explicit .mli file. The bug then appears for a unit which starts with an "open My_module", where My_module doesn't have an explicit interface. The instrumenter would insert a local "let __bisect_table = ..." above this open statement, and this declaration would then be hidden by the open. All local uses of the __bisect_table identifier would refer to the one exported unintentionally from My_module. The fix is to use a globally unique name for the identifier (e.g. some hash of the current unit). Now, if people agree that the feature would be convenient to have in some form:
|
Comment author: @alainfrisch (I've changed the "Summary" to make it less specific.) |
Comment author: @alainfrisch Same bug striked again: LexiFi/landmarks#2 |
Comment author: @alainfrisch |
Can we consider this solved in OCaml 4.08 with the |
Yes, feel free to close this issue |
Original bug ID: 5764
Reporter: @bobzhang
Status: acknowledged (set by @alainfrisch on 2013-09-03T09:20:33Z)
Resolution: open
Priority: normal
Severity: feature
Category: language features
Tags: github
Monitored by: @glondu @hcarty
Bug description
for example file A.ml have a lot of generated code beginning with
__ocaml__blabla, in most cases programmers don't want to expose such functions in A.mli(and it maybe dangerous), so for the automatically generated interface file, it would be nice that the default behavior should hide them, user can write A.mli by hand and expose them if they wish. This also applies generated code by ocaml(lex|yacc)
The text was updated successfully, but these errors were encountered: