> so there's no fundamental reason why not
That another language has done it does not mean there is no fundamental reason not to do it. A fundamental reason can be that its cost/benefit ratio isn't good enough. Other languages weigh language complexity less harshly than Java.
> That's what Kotlin did and it's been very successful
In what sense has it been "very successful"? That the small minority of people on the Java platform that have chosen to use Kotlin like this feature? Currently, there are still more people using Scala, does that mean that all Scala features have been even more successful?
In any event, that would be a different feature, and it will be judged, and then perhaps adopted, separately.
> It's a philosophical objection of the form "mutability is bad", which feels somehow Haskellish and un-Java-like. What happened to being a blue collar language?
That's not the objection, and Java is still blue-collar. Records don't do that not because of some "anti mutation" sentiment but because records are about something else than reducing JavaBean boilerplate. See the discussion on mutability here, https://cr.openjdk.java.net/~briangoetz/amber/datum.html, which I'll reproduce below for your convenience:
> The stricture against mutability is more complex, because in theory one can imagine examples which do not fall afoul of the goals. However, mutability puts pressure on the alignment between the state and the API. For example, it is generally incorrect to base the semantics of equals() and hashCode() on mutable state; doing so creates risks that such elements could silently disappear from a HashSet or HashMap. So adding mutability to records also likely means we may want a different equality protocol from our state description; we may also want a different construction protocol (many domain objects are created with no-arg constructors and have their state modified with setters, or with a constructor that takes only the "primary key" fields.) Now, we've lost sight of the key distinguishing feature: that we can derive the key API elements from a single state description. (And, once we introduce mutability, we need to think about thread-safety, which is going to be difficult to reconcile with the goals of records.)
> As much as it would be nice to automate away the boilerplate of mutable JavaBeans, one need only look at the many such attempts to do so (Lombok, Immutables, Joda Beans, etc), and look at how many "knobs" they have acquired over the years, to realize that an approach that is focused exclusively on boilerplate reduction for arbitrary code is guaranteed to merely create a new kind of boilerplate. These classes simply have too many degrees of freedom to be captured by a single simple description.
> Nominal tuples with clearly defined semantics is something that can make our programs both more concise and more reliable for a lot of use cases -- but there are still use cases beyond the limits of what they can do for us. (That doesn't mean that there aren't things we can do for these classes too -- it just means that this feature will not be the delivery vehicle for them.) So, to be clear: records are not intended to replace JavaBeans, or other mutable aggregates -- and that's OK.