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

Add feature specification for inline classes #2626

Merged
merged 16 commits into from Dec 16, 2022
Merged

Conversation

eernstg
Copy link
Member

@eernstg eernstg commented Nov 11, 2022

This PR adds a feature specification of 'inline classes', which was obtained by taking the current version of the feature specification of 'views' and rename the construct from 'view class' to 'inline class'. It also removes the support for primary constructors (such that we get more time to get that feature just right and introduce it in general, not just for inline classes).

Finally, this PR adjusts the text accordingly. In particular, it changes the word 'superview' to 'superinterface', and it specifies that it is a compile-time error for an inline class to have a type T in the implements clause unless T is an inline class.

The rules about name clashes among "inherited" names are unchanged: It is a compile-time error if an inline class V has superinterfaces V1 and V2, and both of them has a member named m, and it is not the same declaration (e.g., in a diamond superinterface structure). The error is eliminated by adding a declaration named m to V.

Copy link
Member Author

@eernstg eernstg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review response.

A compile-time error occurs unless the inline class declares exactly
one instance variable. Let `v` be the name of said instance
variable. A compile-time error occurs unless the declaration of `v`
has the modifier `final` or the modifier `late`.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has been clarified now. late is an error, no matter what's in the rest of the instance variable declaration. Also, it's an error if there is no final. So late int v = 42; has two errors.

It is allowed for the instance variable to have an initializing expression, but it's hardly useful.

Copy link
Member Author

@eernstg eernstg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for a lot of useful input! I believe the main remaining issue is the syntax super.V2.foo(), used to specify a "superinvocation" of foo in the superinterface (and inline class) V2. This would be needed, in particular, when writing a forwarding member in order to resolve a name clash:

inline class V1 { void foo() {}}
inline class V2 { void foo() {}}
inline class V3 implements V1, V2 { void foo() => super.V2.foo(); }

If we drop that syntax (and do not replace it by something else), I think the only easily expressible way to do the same thing is a cast. Any cast is unsafe, and it is harder to understand the purpose and effect of the code with the cast.

inline class V3 implements V1, V2 { void foo() => (this as V2).foo(); }}

@leafpetersen
Copy link
Member

If we drop that syntax (and do not replace it by something else), I think the only easily expressible way to do the same thing is a cast. Any cast is unsafe, and it is harder to understand the purpose and effect of the code with the cast.

I don't really think this is true. Assigning it to a variable of the super-interface type before calling the method works fine and is perfectly safe.

@eernstg
Copy link
Member Author

eernstg commented Nov 18, 2022

@leafpetersen wrote:

Assigning it to a variable of the super-interface type before calling the method works fine and is perfectly safe.

Right, I was just considering expression forms (because it enables =>, which is probably considered desirable).

@eernstg
Copy link
Member Author

eernstg commented Nov 18, 2022

A couple of extra comments came up. In particular, the ability to do inline-erasure (computing a non-inline type that corresponds to any given inline type, by going repeatedly to the representation type) is finicky, and may need more scrutiny.

Another thing is the fact that the representation object may be null if the representation type is potentially nullable, but this doesn't mean that we can't call the inline class methods. So should the inline type be considered potentially nullable?

@eernstg eernstg mentioned this pull request Nov 25, 2022
Copy link
Member Author

@eernstg eernstg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the I.super.foo syntax, adjusted other locations based on comments. PTAL.

@eernstg eernstg merged commit 3f3b2ad into master Dec 16, 2022
@eernstg eernstg deleted the spec_inline_class_nov22 branch December 16, 2022 10:52
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

Successfully merging this pull request may close these issues.

None yet

7 participants