{"action":"created","issue":{"url":"https://api.github.com/repos/ocaml/ocaml/issues/682","repository_url":"https://api.github.com/repos/ocaml/ocaml","labels_url":"https://api.github.com/repos/ocaml/ocaml/issues/682/labels{/name}","comments_url":"https://api.github.com/repos/ocaml/ocaml/issues/682/comments","events_url":"https://api.github.com/repos/ocaml/ocaml/issues/682/events","html_url":"https://github.com/ocaml/ocaml/pull/682","id":164892235,"number":682,"title":"WIP: Hide bound variables marked with [@ocaml.private] from signatures","user":{"login":"alainfrisch","id":3305274,"avatar_url":"https://avatars.githubusercontent.com/u/3305274?v=3","gravatar_id":"","url":"https://api.github.com/users/alainfrisch","html_url":"https://github.com/alainfrisch","followers_url":"https://api.github.com/users/alainfrisch/followers","following_url":"https://api.github.com/users/alainfrisch/following{/other_user}","gists_url":"https://api.github.com/users/alainfrisch/gists{/gist_id}","starred_url":"https://api.github.com/users/alainfrisch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alainfrisch/subscriptions","organizations_url":"https://api.github.com/users/alainfrisch/orgs","repos_url":"https://api.github.com/users/alainfrisch/repos","events_url":"https://api.github.com/users/alainfrisch/events{/privacy}","received_events_url":"https://api.github.com/users/alainfrisch/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/ocaml/ocaml/labels/work-in-progress","name":"work-in-progress","color":"5319e7"}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":10,"created_at":"2016-07-11T17:34:56Z","updated_at":"2016-07-12T09:37:28Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/ocaml/ocaml/pulls/682","html_url":"https://github.com/ocaml/ocaml/pull/682","diff_url":"https://github.com/ocaml/ocaml/pull/682.diff","patch_url":"https://github.com/ocaml/ocaml/pull/682.patch"},"body":"Not ready for merge!\r\n\r\nThis is a first proposal to address http://caml.inria.fr/mantis/view.php?id=5764 by providing a way to specify that some non-local let-bound pattern variables should not be exposed in their structure.  This is done by detecting a special attribute on pattern variables (the lhs is used in case of or-patterns):\r\nFor instance in\r\n\r\n````ocaml\r\n\r\n  module M = struct\r\n      let x[@ocaml.private], y = 1, 2\r\n  end\r\n````\r\n\r\noutside `M`, only `y` exists.\r\n\r\nThis is not really intended for end-users and more for ppx or other code generators that need to insert declarations for internal uses which should not be exposed in inferred signatures.  (See https://github.com/LexiFi/landmarks/issues/2 for a recent case where such a feature would have been useful.)\r\n\r\nThis PR is to discuss the general idea.\r\n\r\nThe current implementation is not very satisfactory, because it parses the attribute potentially multiple times.  A better approach would probably to add to the `Tstr_value` constructor an explicit list of \"public\" identifiers, rather than recover it from analyzing its patterns.  The logic to parse the attribute would then be nicely located in `Typemod`.\r\n\r\nWhat to do in the toplevel is not completely clear.  Should private identifiers be usable by later phrases?  "},"comment":{"url":"https://api.github.com/repos/ocaml/ocaml/issues/comments/231988847","html_url":"https://github.com/ocaml/ocaml/pull/682#issuecomment-231988847","issue_url":"https://api.github.com/repos/ocaml/ocaml/issues/682","id":231988847,"user":{"login":"xavierleroy","id":3845810,"avatar_url":"https://avatars.githubusercontent.com/u/3845810?v=3","gravatar_id":"","url":"https://api.github.com/users/xavierleroy","html_url":"https://github.com/xavierleroy","followers_url":"https://api.github.com/users/xavierleroy/followers","following_url":"https://api.github.com/users/xavierleroy/following{/other_user}","gists_url":"https://api.github.com/users/xavierleroy/gists{/gist_id}","starred_url":"https://api.github.com/users/xavierleroy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xavierleroy/subscriptions","organizations_url":"https://api.github.com/users/xavierleroy/orgs","repos_url":"https://api.github.com/users/xavierleroy/repos","events_url":"https://api.github.com/users/xavierleroy/events{/privacy}","received_events_url":"https://api.github.com/users/xavierleroy/received_events","type":"User","site_admin":false},"created_at":"2016-07-12T09:37:28Z","updated_at":"2016-07-12T09:37:28Z","body":"@alainfrisch : Concerning the hiding of type (and module) definitions, that's a question that already arises when typing functor applications (see examples below).  The `Mtype.nondep_supertype` function is the basis of the solution.  The solution is sound but not complete.  For more details, see section 5.5 of my \"Modular module system\" paper (http://gallium.inria.fr/~xleroy/bibrefs/Leroy-modular-modules.html).\r\n\r\nExample: the effect of functor `G` is similar to making the type `t` local in the `X` structure.\r\n```\r\n# module G(X: sig type t val x:t end) = struct let x = X.x end;;\r\nmodule G : functor (X : sig type t val x : t end) -> sig val x : X.t end\r\n```\r\nSometimes it can be done, other times it cannot:\r\n```\r\n# module B = G(struct type t = int let x = 1 end);;\r\nmodule B : sig val x : int end\r\n# module C = G(struct type t = X|Y let x = X end);;\r\nError: This functor has type\r\n       functor (X : sig type t val x : t end) -> sig val x : X.t end\r\n       The parameter cannot be eliminated in the result type.\r\n        Please bind the argument to a module identifier.\r\n```"}}
{"actor":{"display_login":"xavierleroy"}}