let editor: IntEditor = AnyIntEditor(
initialValue: nil,
setValue: { print($0) })
editor.setValue(12) // prints "12"
Now, the definition of AnyIntEditor.setValue(_:) is very troubling, because it looks like it starts an infinite loop. But it does not, as it actually calls the property (Xcode 11.3):
struct AnyIntEditor: IntEditor {
var initialValue: Int?
var setValue: (_ value: Int) -> Void
func setValue(_ value: Int) {
setValue(value) // calls the property
}
}
So here is my question: is it a guaranteed behavior, or some unintended side-effect of an implementation detail in the compiler that no one should rely on?
I found this in the compiler source code, in ConstraintSystem::compareSolutions:
[...] a property is better than a method (because a method is usually immediately invoked).
Of course this piece of code may be unrelated to my question. But if it is, it looks that the answer is a positive yes. I admit that I'd prefer finding something which is more convincing, such as a test, or a confirmation from a knowledgable person. May I summon @Slava_Pestov?
This is an inconsistency in the behavior of the compiler, which may well deserve an issue. I won't open any, because this inconsistency may well be required as a support for other more important compiler behaviors. I just don't know.
Yet, I find this topic interesting, because the current state of the compiler gives an objective argument against sharing the same name for a closure property and a method, which is that this sharing is not guaranteed to be accepted by the compiler for all signatures. The pattern does not always work well.
There is a verbose workaround which preserves the pattern, though: