Open ejstrobel opened 9 years ago
+1 to stable value case.
Also, text "And because we have the value defined as a val, we cannot fix the above example by overriding value as a lazy val, an otherwise decent way of fixing such a sample." is incorrect: it's ok to override val
with lazy val
, see faq and repl output:
scala> trait Foo { val value: String }
defined trait Foo
scala> trait Bar extends Foo { val uppercase = value.toUpperCase }
defined trait Bar
scala> trait MyValue extends Foo { lazy val value = "hello" }
defined trait MyValue
scala> new Bar with MyValue
res1: Bar with MyValue = $anon$1@1ce5ab88
scala> (new Bar with MyValue).uppercase
res2: String = HELLO
You guys are right. Will be fixed.
I have 2 issues here, the first is a that the sentence "And this freedom is important, because a val for example restricts the way this value can get initialized - only at construction time." is not totally correct: An abstract val may be implemented by a lazy val which is initialized on first use.
The second and more important is about interface design. Yes a parameter-less def gives more flexibility in implementing. But on the other hand, it makes less of a promise to the interface user. Sometimes I really do want to promise that a property is "stable" (or immutable), as in:
Here Foo promises a stable value, which may not change. Therefore I do not need to re-calculate prompt on every iteration of the loop.
I suggest adding "... unless your interface needs to promise a stable value" to the rule.