Skip to content

spec: document definition of comparable #50791

Description

@griesemer

Title says it all. Reminder issue.

cc: @ianlancetaylor
cc: @findleyr
cc: @mdempsky

Activity

  1. added
    NeedsDecisionFeedback is required from experts, contributors, and/or the community before a change can be made.
    on Jan 25, 2022
  2. added this to the Go1.18 milestone on Jan 25, 2022
  3. self-assigned this
    on Jan 25, 2022
  4. rsc commented on Jan 25, 2022

    @rsc
    Contributor

    What would it be an alias of?

  5. griesemer commented on Jan 25, 2022

    @griesemer
    ContributorAuthor

    At the moment we have the equivalent of

    type comparable <magic_comparable_interface_literal>

    in the universe scope.
    If it were an alias, it would be the same but as an alias declaration.

    As it is now, there is an underlying type, which is that magic interface which doesn't have a name and can't be printed correctly.

    I can't think of a way to make the distinction visible inside Go at the moment, but it's visible through the go/types API: This code prints the underlying type of comparable. Because there's no proper literal for it, it prints interface{} which is misleading at best. The actual underlying type behaves correctly (test).

    If we make comparable an alias for this magic interface literal, the underlying type would be itself and could be printed as comparable.

    Perhaps it should be a "basic" type like int, etc.

  6. rsc commented on Jan 25, 2022

    @rsc
    Contributor

    I'm confused about why making it an alias would change the underlying type, but perhaps my understanding that point that doesn't matter. Totally agree about it being its own underlying type. Calling it a 'basic' type would work too.

  7. findleyr commented on Jan 25, 2022

    @findleyr
    Contributor

    Agree about it being its own underlying type, which means it can't be a defined type. I think making it a basic type (like unsafe.Pointer) could be problematic. We'd have to introduce a new BasicKind, which behaves rather differently than all other basic kinds. This would require a updating a lot of code in tools.

    Making comparable an alias for "the magic comparable interface" makes sense to me. Similar to any, we'd have special handling for formatting "the magic comparable interface" as comparable, but unlike any we don't have to implement this via pointer tracking: we have a bit on Interface that tells us if it is comparable.

  8. griesemer commented on Jan 25, 2022

    @griesemer
    ContributorAuthor

    Ok, we all agree that comparable's underlying type is itself.

    Need to mention this in the spec in the section on underlying types, and need to adjust implementation accordingly.

    See conclusion.

  9. added
    DocumentationIssues describing a change to documentation.
    and removed
    NeedsDecisionFeedback is required from experts, contributors, and/or the community before a change can be made.
    on Jan 25, 2022
  10. changed the title [-]spec: should `comparable` be an alias type (like `any`)[/-] [+]spec: document that `comparable` is its own underlying type[/+] on Jan 25, 2022
  11. gopherbot commented on Jan 25, 2022

    @gopherbot
    Contributor

    Change https://golang.org/cl/380754 mentions this issue: go/types, types2: underlying type of comparable is itself

  12. ianlancetaylor commented on Jan 25, 2022

    @ianlancetaylor
    Contributor

    If we ever permit variables to have type comparable, we'll have to explain what happens if you call reflect.TypeOf on a pointer to such a variable. Presumably the reflect.Kind will be Interface, because it is, after all, an interface type. For that reflect.Type, it seems to me that the Name method should return "comparable". That is what happens with the predeclared type error: the Name method returns "error". It is also what happens with the predeclared type int.

    I think that implies that comparable is a defined type, defined in terms of a magic interface type, just as int is a defined type defined in terms of a magic integer type. I don't know what consequences that would have for the go/types package, and it's not necessarily essential that go/types and reflect act the same way.

  13. griesemer commented on Jan 25, 2022

    @griesemer
    ContributorAuthor

    The underlying type of error though is not error, it's the respective interface literal. This is different from other predeclared types such as int.

    Making comparable a defined type like int is also a possibility, and perhaps the more correct choice. @findleyr is correct though that this will require some changes that will ripple through various packages' APIs because we'll add a new basic type. But that may be cleaner than using an alias to an interface which still needs some magic bit to indicate it is the comparable interface (this shows up in imports, for instance).

  14. findleyr commented on Jan 25, 2022

    @findleyr
    Contributor

    FWIW, when I wrote it my comment I didn't see much advantage to having comparable be a basic type. If we decide that is most correct, we should represent it accurately in go/types.

  15. 29 remaining items

  16. changkun commented on Jan 27, 2022

    @changkun
    Member

    It would be an interesting story to hear about the failure due to the proposal doc have only two places mentioning operator method but none of them mentioned about the sunk of that approach and only says "unplanned".

  17. griesemer commented on Jan 27, 2022

    @griesemer
    ContributorAuthor

    It would be an interesting story to hear about the failure due to the proposal doc have only two places mentioning operator method but none of them mentioned about the sunk of that approach and only says "unplanned".

    There's only so much time in one's life to write down every single path taken which ended in a dead end. Sometimes it's just two short mentions... :-)

  18. ianlancetaylor commented on Jan 27, 2022

    @ianlancetaylor
    Contributor
  19. gopherbot commented on Jan 29, 2022

    @gopherbot
    Contributor

    Change https://golang.org/cl/381896 mentions this issue: spec: add section on comparable constraint

  20. fzipp commented on Feb 7, 2022

    @fzipp
    Contributor

    When printing the underlying type of comparable, we can print interface{comparable} which is a valid Go type.

    In short: The underlying type of comparable is not itself. Instead we define comparable similar to error, as a defined type with a magic underlying type that still can be printed as valid Go.

    I think this should be reflected by the declaration of comparable in the builtin documentation package:

    https://github.com/golang/go/blob/master/src/builtin/builtin.go#L102

    -type comparable comparable
    +type comparable interface{ comparable }
  21. added a commit that references this issue on Feb 11, 2022
  22. locked and limited conversation to collaborators on Jun 22, 2023
  23. added a commit that references this issue on Apr 29, 2024
    9152e21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions