408399 (15) [Avatar] Offline
#1
Example says:
<code>
class SubscribingUser(val email: String) {
val nickname: String

get() {
return email.substringBefore('@')
}
}
</code>

And says the line "get() {" is a "property getter declaration"

Text says:
The property nickname doesn't have a field to store its value. It only has a getter with the implementation you provided. The computation is processed on every access to the property.

Note that you don't have to use the full syntax with curly braces; you might write simply

<code>
get () = email.substringBefore('@')
</code>

Problem:
The example doesn't make sense within the available information in chapter 2. I'm not sure which of these two explanations is correct:

Possible explanation 1
The example is broken and should be something like

<code>
class SubscribingUser(val email: String) {
getNickname() {
return email.substringBefore('@')
}
}
</code>

Possible explanation 2
<code>
val nickname: String
get () {
...
}
</code>
is the syntax required to declare that a field does NOT exist(!) but that nevertheless a getNickname() property accessor does exist.


Number 2 seems like a very ... convoluted and ... counterintuitive ... syntax to declare that nickname does NOT really exist, because declaring an immutable field is a perfectly reasonable thing to do ... but it still is a field. If number 2 is actually the true explanation, then it screams loudly, jumps up and down, and holds its breath like a child, in demand of an explanation of what each part of that convoluted thing means. smilie
Svetlana Isakova (9) [Avatar] Offline
#2
Hi! Thanks for your feedback.

The compiler generates or omits the backing field depending on the code you write in the getter. The general getter syntax stays the same for both scenarios. Thus the compiler hides the implementation details behind the concept of "property".

We should emphasize it more clearly. Chapter 4 gives more details on that (answering screaming and jumping request for the explanation); we can add an explicit reference to ch 4 at the end of 2.2.3 as well.
408399 (15) [Avatar] Offline
#3
The screaming and jumping Number 2 thanks you for adding the cross-reference to 4.1.2.

Another thing which might help (not sure whether this belongs in 2.2.3 or 4.1.2) would be to say that the compiler drops the backing field, because it is not referenced in the custom getter, and there is no custom setter (or whatever the actual logic the compiler uses is).

Now a couple questions about the explanation in 4.1.2:

Is it correct that PrivateUser.nickname is settable, but SubscribingUser.nickname is not settable? I think FacebookUser.nickname would be settable, but is that correct?

Perhaps it would be useful to point out the impact on setters of the different implementations?
Svetlana Isakova (9) [Avatar] Offline
#4
They all are declared as val, which are readonly properties missing setters. So, they all are not settable.
408399 (15) [Avatar] Offline
#5
Very cool, I missed that!
That is a good illustration of a fine point of Kotlin one must watch for, when reading it. smilie
408399 (15) [Avatar] Offline
#6
Hi,
It might be helpful to give a link to the formal definition, so people can see what's going on. http://kotlinlang.org/docs/reference/grammar.html#property That also links them to http://kotlinlang.org/docs/reference/properties.html

Hmm, giving people links to the reference docs to help clarify things also helps to get your readers used to looking at the reference docs, and using your guide with them, so that they can have maximum understanding. If you want to promote use of eBooks, that might also happen.