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

Only allow pure/specifically annotated enums to be overloaded #468

Closed
metagn opened this issue Jul 25, 2022 · 5 comments
Closed

Only allow pure/specifically annotated enums to be overloaded #468

metagn opened this issue Jul 25, 2022 · 5 comments

Comments

@metagn
Copy link
Contributor

metagn commented Jul 25, 2022

Abstract

Require an annotation/pragma (preferably a repurposed/renamed {.pure.}) on enum types to be able to use their fields as overloads.

Motivation

The following code works without, but breaks with --experimental:overloadableEnums (nim-lang/Nim#20077):

type Foo1 = enum abc
block:
  type Foo2 = enum abc
  doAssert abc is Foo2

A more important version of this problem is with imports. There are multiple tests for this, both without and with imports.

However, this is mostly intended behavior of overloadableEnums. Consider the following:

# a.nim
type A* = enum
  Left, Right

# b.nim
type B* = enum
  Left, Down

# c.nim
import a, b

type C* = enum
  Left, South

let what = Left

An ambiguity error is the most sensible outcome here; with --experimental:overloadableEnums there is an ambiguity error, without it, what has type C. So the behavior of overloadableEnums here is preferred.

The difference between the example code and the test cases is that in the example case, the enums would normally have the {.pure.} annotation, while other enums may not necessarily need fancy behavior like this. So maybe the best solution is to restrict this overloading behavior to pure enums, while also removing any remaining need for qualification of pure enums.

Description

pure as is is generally regarded to be useless and deserving deprecation because of it not working as documented, so giving it new meaning that is compatible with its common/intended use is acceptable. If a new name for this is used instead of pure, then pure can be deprecated and alias to the new name.

This will make the transition to --experimental:overloadableEnums easier for normal projects, as they can gradually enable certain enums to work this way. Projects already using --experimental:overloadableEnums will have to annotate their enums with pure. We could make pure the default somehow but this doesn't fit the narrative of them being "fancy" enums.

Code Examples

# a.nim
type A* {.pure.} = enum
  Left, Right
# b.nim
import a

type B* {.pure.} = enum
  Left, Down

when isMainModule:
  assert not compiles((let left = Left; left))
  assert compiles((let left: A = Left; left))
  assert compiles((let left: B = Left; left))
# c.nim
import a, b

type C* = enum
  Left, South

when isMainModule:
  assert Left is C
# d.nim
import c

type D* = enum
  Left, Back

when isMainModule:
  assert Left is D

Backwards Compatibility

Backwards incompatible for projects already using overloadableEnums however the fix is extremely adaptable and simple.

If pure is used, the behavior of the old pure would be removed, but this can still only be under --experimental:overloadableEnums.

@Araq
Copy link
Member

Araq commented Jul 26, 2022

The problem with this proposal is that it keeps two distinct forms of enum in Nim. Ideally there is only one enum construct that just works.

@metagn
Copy link
Contributor Author

metagn commented Aug 1, 2022

Should these tests be removed then? Keeping the tests means we would need to keep some way to opt in/out of overloadableEnums, meaning there would still be 2 enum constructs.

@al6x
Copy link

al6x commented Aug 31, 2022

I dislike this proposal. Overloadable enums looks like a proper way enums should work. It should not need any annotations, it should just work, by default.

@Araq
Copy link
Member

Araq commented Sep 1, 2022

Should these tests be removed then?

Yes.

@metagn
Copy link
Contributor Author

metagn commented Sep 3, 2022

Should these tests be removed then?

Yes.

Done in nim-lang/Nim#20298

@metagn metagn closed this as completed Sep 17, 2022
@metagn metagn closed this as not planned Won't fix, can't repro, duplicate, stale Sep 17, 2022
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

3 participants