Let's go to Crazy Town for a second... (and I mean it, this could be insane)

Today, field initializers and instance initializers certainly don't have any constructor parameters in scope, because they apply to /all/ constructors. But for records we've discussed mandating that all constructors must funnel through the primary one (which I think is good). That means there is really only one true constructor. Is it insane to say that initializers, then, only apply to that primary constructor, and ergo we allow that constructor's parameters to be referenced in initializers?

It's not insane, but it does have cost.  Let me pull on that thread ...

Right now, { ... } has a meaning in classes, which is that it runs before the constructor (with field initializers).  All things being equal, we'd like for constructs that are common to records and classes to mean the same thing in both; not only does this minimize confusion, but it also plays into a bigger goal for records, which is: records are "just" a macro for a specific class declaration. This goal minimizes the perceived complexity for users ("this thing is just like this other thing"), and also simplifies the story for refactoring back and forth.

What you're really saying is to change the timing of instance initializers for records, to run _inside_ the default constructor, after the super-call / default field initializations.  This is one subtle difference from classes; the other is that the construction parameters are in scope (meaning that the meaning of `x` changes too.)  Arguably, you should do the same for field initializers. This seems a prety big change, to eliminate an utterance of "Foo".

(again, imho, "the right amount of repetition is no repetition")

I'd say instead: every bit of repetition should carry its weight?


Reply via email to