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

Make delegate work for records #587

Closed
ice1000 opened this issue May 9, 2024 · 9 comments
Closed

Make delegate work for records #587

ice1000 opened this issue May 9, 2024 · 9 comments

Comments

@ice1000
Copy link

ice1000 commented May 9, 2024

Is your feature request related to a problem? Please describe.

public interface Bro {
  record Bruh(@link Bro bro) implements Bro {}
  void callFromBabylon();
}

Delegation with record fields is unsupported.

Describe the solution you'd like
Support it.

Describe alternatives you've considered
Hand-write the delegation.

Additional context
Records are introduced in Java since 16 IIRC

@rsmckinney
Copy link
Member

Hi @ice1000.

To make records play well with delegation we would need to have control over the constructors where the delegates could be passed in and encapsulated exclusively for use with delegation. But this is not the case, Java records prohibit additional private state.

While we could include the delegates as normal record parameters, at that point the record ceases to be a record. This breaks encapsulation where the delegates, which are implementation detail, become publicly accessible as part of the record's data.

Generally, their value-based nature confines records to a very limited amount of customization.

More generally, I would say instead of using delegation for records, use default and private methods in the interface to implement a stateless API. Then your record can implement the interface without additional code. Otherwise, if delegation is required i.e., the interface requires state, your model cannot be satisfied with a record, you must instead use a class.

@ice1000
Copy link
Author

ice1000 commented May 10, 2024

Honestly I think it's okay for the delegate object to be public, here I'm only looking for a code generator for interface implementations that just forwards to another field. But I can see that manifold is not what I'm looking for. Thanks for your answer!

@rsmckinney
Copy link
Member

here I'm only looking for a code generator for interface implementations that just forwards to another field.

That’s precisely what @link does.

@ice1000
Copy link
Author

ice1000 commented May 10, 2024

here I'm only looking for a code generator for interface implementations that just forwards to another field.

That’s precisely what @link does.

That doesn't work for records :/

@rsmckinney
Copy link
Member

Right. But can I ask why you would like the type to be a record vs. a class? I just want to understand your use-case; perhaps it could justify supporting records with delegation. Thanks

@ice1000
Copy link
Author

ice1000 commented May 10, 2024

Right. But can I ask why you would like the type to be a record vs. a class? I just want to understand your use-case; perhaps it could justify supporting records with delegation. Thanks

It's very simple, I'm basically trying to simulate traits using interfaces, and I use records to do the newtype design pattern: I want certain traits to be inherited while reimplements some others. So I wish this can be done by hand writing the reimplantation and leave the others to the link annotation.

@rsmckinney
Copy link
Member

Ok. In my view records are unsuitable for the basis of a newtype, they force you to expose impl detail that should be encapsulated. shrug

Anyhow, still considering support for records for the case where data members also supply interface contract such as hasName() for a Named interface implemented by a Person data member.

The change to support records is trivial and will likely make it in the next release, probably within the next couple days. Thanks for resurfacing this topic!

@ice1000
Copy link
Author

ice1000 commented May 10, 2024

Thank you!

@rsmckinney
Copy link
Member

No problem. To be clear, you can already use delegation with records with the Java compiler, this issue is specific to IntelliJ support. A new Intellij plugin release will be available EOD Monday or Tuesday.

rsmckinney added a commit to manifold-systems/manifold-ij that referenced this issue May 15, 2024
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

2 participants