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

Aliased exn type is not extensible #9147

Closed
bobzhang opened this issue Nov 27, 2019 · 7 comments
Closed

Aliased exn type is not extensible #9147

bobzhang opened this issue Nov 27, 2019 · 7 comments

Comments

@bobzhang
Copy link
Member

bobzhang commented Nov 27, 2019

# Sys.ocaml_version;;
- : string = "4.08.1"
# type u = exn;;
type u = exn
# type u += A of int;;
Error: Type definition u is not extensible
# type exn += A of int;;
type exn += A of int

Note I think it is actually more helpful to make exn distinct from open types (exn is important), but this inconsistency is intentional?

@Octachron
Copy link
Member

This behavior is not specific to exn at all, you need to declare the aliased type u as extensible itself:

type u = exn = ..
type u += A of int

This should be precised in more detail in the manual.

@gasche
Copy link
Member

gasche commented Nov 28, 2019

I find the behavior a bit surprising; when is it the right thing to do to close extensibility on aliasing, and why is it the default? (Could we have a syntax for closing extensibility if the other option was the default?).
cc @lpw25 @garrigue

I tend of think of let/type/module/exception/etc. a = b, when a and b are names in the appropriate syntactic category, as creating an alias that can be used in the exact same way the original name could, and any part of the system that breaks this expectation adds friction.

@trefis
Copy link
Contributor

trefis commented Nov 28, 2019

How is that different from not reexporting labels / constructors?

@lpw25
Copy link
Contributor

lpw25 commented Nov 28, 2019

The behaviour is indeed modeled on the behaviour of records and variants:

# type t = T;;
type t = T
# type s = t;;
type s = t
# type r = s = T;;
Line 1, characters 0-14:
1 | type r = s = T;;
    ^^^^^^^^^^^^^^
Error: This variant or record definition does not match that of type s
       Their kinds differ.
# type r = t = T;;
type r = t = T

@gasche
Copy link
Member

gasche commented Nov 28, 2019

If I understand it correctly, your point is the following. If you alias a variant type, you don't automatically get the variant constructors in scope, you still have to go through old type to access them (and old-type-variants are compatible with the alias type). With exensible types, you don't automatically get the power to extend the lias, you still have to go through the old type to extend it (and newly-extended constructors are compatible with the alias type).

@xavierleroy
Copy link
Contributor

Is there any action required here? I'd like to close this report.

@lpw25
Copy link
Contributor

lpw25 commented Apr 9, 2020

This is the intended behaviour and I don't think there is a strong reason to change it, so I'm closing.

@lpw25 lpw25 closed this as completed Apr 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants