# Aliasing a functor application in a module interface?

**URL:** <https://discuss.ocaml.org/t/aliasing-a-functor-application-in-a-module-interface/8546>\
**Category:** Learning\
**Tags:** module, language\
**Created:** [September 29, 2021, 3:39pm UTC](https://discuss.ocaml.org/t/aliasing-a-functor-application-in-a-module-interface/8546 "2021-09-29T15:39:28Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![gasche](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/gasche/32/4_2.png) [@gasche](https://discuss.ocaml.org/u/gasche)\
**Post date:** [September 29, 2021, 3:39pm UTC](https://discuss.ocaml.org/t/aliasing-a-functor-application-in-a-module-interface/8546/1 "2021-09-29T15:39:28Z")

</div>

I keep trying to write things like this in module _interfaces_

```ocaml
module Var : Map.OrderedType
module VarSet = Map.Make(Var)
(* ^
  Syntax error: 'end' expected *)

```

This is rejected, it appears that `module Foo = Bar` is only allowed when `Bar` does not contain module applications (see the manual: [Type-level module aliases](https://ocaml.org/releases/4.12/manual/modulealias.html#s%3Amodule-alias)). Instead I have to write the following, which is accepted and seems to do what I want (but I’m sure sometimes it doesn’t for a subtle reason):

```ocaml
module Var : Map.OrderedType
module VarSet : module type of Map.Make(Var)

```

**Question** : why can’t we just write the module alias?  
(I guess I should know, but I forgot long ago.)

(cc @garrigue, @lpw25, @Drup)

P.S.: Is this something that “transparent module ascriptions” are supposed to help for? (I thought they were required to mention a functor _argument_ inside an alias, not to alias functor applications.)

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [September 29, 2021, 4:47pm UTC](https://discuss.ocaml.org/t/aliasing-a-functor-application-in-a-module-interface/8546/2 "2021-09-29T16:47:33Z")

</div>

I’m sure you must have a good reason, but out of curiosity, could you not do `module VarSet : Map.S with type key = Var.t`?

---

<div class="post-metadata">

**Author:** ![lpw25](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lpw25/32/144_2.png) [@lpw25](https://discuss.ocaml.org/u/lpw25)\
**Post date:** [September 29, 2021, 5:00pm UTC](https://discuss.ocaml.org/t/aliasing-a-functor-application-in-a-module-interface/8546/3 "2021-09-29T17:00:33Z")

</div>

See [this PR and associated discussion](https://github.com/ocaml/ocaml/pull/10435)

---

<div class="post-metadata">

**Author:** ![gasche](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/gasche/32/4_2.png) [@gasche](https://discuss.ocaml.org/u/gasche)\
**Post date:** [September 29, 2021, 8:02pm UTC](https://discuss.ocaml.org/t/aliasing-a-functor-application-in-a-module-interface/8546/4 "2021-09-29T20:02:45Z")

</div>

Good question! Problems with `Map.S with type key = Var.t` include the following:

- It’s more work than `= Map.Make(Var)` (which I have to use in the implementation anyway), I have to find the `S` and the `key`
- Some functors don’t give an explicit name to their output signature (`module F (M : sig .. end) : sig .. end = struct ..end`), and then there is no `S` to refer to.
- Some modules signatures export many types, and submodules, and it’s a lot of work to come up with the right `with type ... = ...` constraints.
- This approach creates maintenance work: if tomorrow `Map.S` gets a new abstract type, I need to go back and add a new `with type = ...` constraint. Coupling was introduced by depending on the details of the signature.

---

<div class="post-metadata">

**Author:** ![gasche](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/gasche/32/4_2.png) [@gasche](https://discuss.ocaml.org/u/gasche)\
**Post date:** [September 29, 2021, 8:10pm UTC](https://discuss.ocaml.org/t/aliasing-a-functor-application-in-a-module-interface/8546/5 "2021-09-29T20:10:19Z")

</div>

Thanks @lpw25 for the excellent pointer. What I understand from [your post in the thread](https://github.com/ocaml/ocaml/pull/10435#issuecomment-853791493) is that the main blocker is the fact that module aliases are currently used in `-no-alias-deps` mode, they are only present at type-checking time and not present as runtime in the module data. Morally, this breaks for functor applications which need to be computed somewhere.

(If we hadn’t coupled module-aliases with “weak dependencies” as a poor human’s namespacing system, we wouldn’t have any problem with functor applications at all, if I understand correctly.)

If we want to have the option to have “erased (absent) aliases” and “present aliases”, without a syntax for the user to explicitly make the distinction, we need to figure out how to decide which alias goes in which category, in a way that has nice properties – in particular, is stable by substitution/reduction when a functor application can be simplified away to a specific module.
