Skip to content
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

Module aliasing and ability to reference the current and parent modules #6324

Closed
vicuna opened this issue Feb 7, 2014 · 9 comments
Closed

Comments

@vicuna
Copy link

vicuna commented Feb 7, 2014

Original bug ID: 6324
Reporter: pw374
Status: acknowledged (set by @damiendoligez on 2014-07-16T13:29:05Z)
Resolution: open
Priority: normal
Severity: feature
Category: typing
Related to: #6323
Monitored by: @hcarty @yakobowski

Bug description

I've always wanted to be able to reference the current module, which also means being able to reference the parent module(s).

An idea is to be allowed to prefix a type or a variable with the current module's name.
As in

    module X = struct type t = A let a : X.t = A end

However this would probably break existing programs, or worse: change their semantics, so let's drop it.

But by using a new syntax, we could have this without breaking preexisting programs:

    module X as Y = struct type t = A let a : Y.t = A end

and I believe it would be quite useful!

Perhaps the keyword as is not the best, that can certainly be discussed.

Additional information

It's related to #6323
as this feature would allow the programmer to fairly easily solve an impossible problem (i.e., the fact that currently some working .ml files just cannot have an .mli that matches its full interface).

@vicuna
Copy link
Author

vicuna commented Feb 7, 2014

Comment author: @dbuenzli

I'm having this problem right at the moment where I need to reorder things in a non natural way documentation wise. Below I would like to be able to put Renderer.Buf before Renderer.Private in the generated docs. I'm not able to do so because Renderer.Private uses module type of Buf and I'm not able to tell him I want the toplevel one.

module Buf : sig (* A buffer module, the client does need a renderer to use them *) 
   type t 
end

module Renderer : sig 
   type t 

   module Private : sig 
      module Buf : sig  (* used by renderer backends may need renderers 
        include module type of Buf 
        ...
      end
   end 

   module Buf : sig (* a few Buf functions for clients that need a renderer to work *)
   end
end

@vicuna
Copy link
Author

vicuna commented Feb 7, 2014

Comment author: @gasche

I personally find this rather ugly, and in my experience this kind of hacks does not generalize very well. For example, if you expect Y.t (for a private t) to refer to the external view of t (say in the context of the work by Grégoire, Jacques and Alain on runtime type representations), this is useful but you quickly end up wanting to be able to name this type also "from the point of view of further sealings", eg. when (X : S') is later used in the source.

This could be useful to speak about the double-vision problems in recursive module (where there really is a canonical sealing we're talking about).

@vicuna
Copy link
Author

vicuna commented Feb 7, 2014

Comment author: pw374

Not being able to reference the current module also means that this (very simple program) doesn't work:

type t = A
open String
let x : t = A

And I've found this very annoying for at least 8 years.

N.B. One could argue that 'open' should only be used before any type declaration (and I'd agree), but it's not forbidden to do so, so it doesn't change anything. And this is only a trivial toy example, so let's not be tempted by stating that it represents how people do or don't program. :-)

@github-actions
Copy link

This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.

@github-actions github-actions bot added the Stale label May 13, 2020
@gasche gasche removed the Stale label May 13, 2020
@gasche
Copy link
Member

gasche commented May 13, 2020

I believe that the pain points expressed are still valid, but it is still unclear to me what would be a good approach (satisfying and not too ad-hoc).

@github-actions
Copy link

This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.

@Lupus
Copy link

Lupus commented Feb 2, 2023

Another user here still suffering from the necessity to create some type aliases in order to create .mli files for my modules. Couple of nested modules, each defining type t and referring to parent type t and here we go. In .ml OCaml is able to infer this and I don't have to create type aliases (although it prints it a bit unfriendly in the errorms, like t/1 and t/2). Adding aliases in .mli forces you to add them to .ml as well, and then your IDE picks up aliases in all types when you do mouse hover and it's really annoying. Having the convention of calling main module type just t without some mechanism to reference "outer" t along with convention to pack types in modules aggressively for record disambiguation to work leads to this constant headache for OCaml users.

@lpw25
Copy link
Contributor

lpw25 commented Feb 2, 2023

Have you tried using type t := ...:

module M : sig
  type t
  module N : sig
    type m := t
    type t
    val of_m : m -> t
  end
end

This feature was added after this issue was created. It doesn't require you to change the .ml file.

@Lupus
Copy link

Lupus commented Feb 2, 2023

Wow, looks promising, thanks! I was trying to google this up, but landed on this issue. Hopefully future googlers will run into this snippet next time and will use this trick! 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants