The modifier "component" is too close to the "property"
        modifier I wanted to include years ago, it's just to sugary
        for its own good.


    You know the rule; mention syntax and you forfeit the right to
    more substantial comments....


I'm talking about the semantics, especially the fact that equals/hashCode and toString() are derived from.

Except that equals/hashCode have nothing to do with the "component" modifier _at all_.  They are derived from the _state description_, in terms of the _accessors_, whose existence is implied directly by the _state description_.

If a concrete class (including records) have a state description, then equality means "all the components are equal".  The different between carrier classes and records is the plumbing between the representation and API; one can be automated, the other might require manual assistance to complete.

As far as i understand, the carrier class syntax
  class Point(int x, int y) { ... }
means that
- if it's not a concrete class, the implementation should provide an implementation for the canonical constructor and accessors, - if it's an interface or an abstract class, the accessors are generated as abstract methods.

Then declaring a field as "component" generates the canonical constructor, the corresponding accessor and toString/equals/hashCode.

This isn't quite right.

 - The state description implies the existence of specific API elements: canonical constructor (for constructible entities) and accessors.
 - Deconstruction is derived from the accessors.
 - Since the state description is complete, the default equals/hashCode/toString is again derived from the accessors (for concrete entities).  - If the user provides the required API elements, nothing else is "generated".

If the required API elements are not present, and they _can_ be derived, they are.  This is always true for records.  For accessors, this is true when the component is backed by a `component` field, otherwise the compiler will force you to explicitly declare it.  For constructors, if _no_ constructor is specified, an empty compact constructor will be derived.  Further, for a compact constructor, if a field is a component field, the component parameter will be implicitly committed to the field at the end of the constructor.

So the role of `component` fields is limited to two things: if there is no accessor, you get one, and the compact constructor will implicitly commit the field for you.  A record is a carrier class which has component fields for all components.

As i said earlier, I think that providing an implementation for toString/equals/hashCode is not a good idea.

What this implies is that you you don't buy the (quite fundamental!) notion that a record is a degenerate case of a carrier.  Currently, a record is equivalent to a carrier class that (a) extends Record, (b) is final, and (c) has private final component fields for each component.  If you want to "separate" the default semantics of the Object methods, you have to separate the notion of carrier from records.  Is that what you're suggesting?

Given that the class can be mutable, generating equals and hashCode hide important details that are

Please stop saying "generate".  (Actually, please stop *thinking* it.)  That's Lombok-think.

Reply via email to