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

reconsider syntax for internal / external implementation of interfaces #2293

Closed
zygoloid opened this issue Oct 15, 2022 · 2 comments
Closed
Labels
design idea An issue recording a specific language design idea that folks can potentially pick up.

Comments

@zygoloid
Copy link
Contributor

We've ended up with a somewhat inconsistent syntax for stating that a class versus an interface implements an interface internally / externally:

class C {
  // Internal implementation
  impl as X;
  // External implementation
  external impl as X;
}

interface D {
  // Internal implementation
  extends X;
  // External implementation
  impl as X;
}

As well as being a little inconsistent between classes and interfaces, it also results in excess verbosity for impls at the top level, where the external keyword is always required in order to make those declarations consistent with ones at class scope.

I think there's an alternative here that we've not considered: use the interface approach in classes too:

class C {
  // Internal implementation
  extends X {
    // ...
  }
  // External implementation
  impl as X {
    // ...
  }
}

In the case of a separate declaration and definition of the implementation, I think it'd be least surprising to use the following syntax:

class C {
  extends X;
}
// Not `extends C as X { ... }`
impl C as X { ... }

More broadly, I wouldn't allow extends to specify an "implementing type" at all -- it would always be Self. This would disallow conditional conformance with an internal impl, such as in this example from the design:

class X(T:! Type) {
  impl X(i32) as Foo {
    fn F[me: Self]();
  }
  impl X(i64) as Bar {
    // ❌ Illegal: name conflict between `Foo.F` and `Bar.F`
    fn F[me: Self](n: i64);
  }
}

... for which neither impl would be expressible any more. I think that's reasonable: saying that the interface of a generic class contains member names from an impl for a special case of that generic class seems likely to be confusing. Conditional conformance would still be possible, but only for external implementations.

@zygoloid zygoloid added the design idea An issue recording a specific language design idea that folks can potentially pick up. label Oct 15, 2022
@josh11b
Copy link
Contributor

josh11b commented Nov 2, 2022

Previous discussion: #995

@chandlerc
Copy link
Contributor

Previous discussion: #995

Can we close this as a duplicate of #995 since that one is already open and seems to be directly considering the exact same question?

@zygoloid zygoloid closed this as not planned Won't fix, can't repro, duplicate, stale Nov 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design idea An issue recording a specific language design idea that folks can potentially pick up.
Projects
None yet
Development

No branches or pull requests

3 participants