```data class Node( val author: String, val mess...
# announcements
l
Copy code
data class Node(
	val author: String,
	val message: String,
	val children: List<Node>,
	val parent: Node = this
)
why is
this
not defined in this context ? context: Im making a chat client with tree structure instead of linear conversation. Every message is a comment on the message it replies to, except the root node which is a comment on itself (or should i make it nullable? i like to avoid nullability whenever possible)
k
this
is not yet created
l
is it even possible for an object to contain an immutable reference to itself?
k
i don’t think so
but you can make it Nullable
Copy code
data class Node(
	val author: String,
	val message: String,
	val children: List<Node>,
	val parent: Node?
)
l
yeah thats what i was considering as an alternative, but i'd prefer to avoid nullability if possible
k
Copy code
data class Node(
    val author: String,
    val message: String,
    val children: List<Node>,
    var parent: Node
) {
    init {
        parent = this
    }
}
you can try this as well to avoid null ability
l
how would i specify a different node as parent in this case?
oh
its not immutable anymore
k
yup indeed but an alternate for avoiding nullability
l
is it possible with neither nullability nor mutability?
k
not in my knowledge
m
You should not create recursive data class instances. Calling
.toString()
,
.equals()
or
.hashCode()
on them will cause a
StackOverflowError
.
👍 2
l
fair point
will go with nullability then for my case
m
Wil work for your case, but not fix the SOE 🙂
l
if i use null for the root node's parent i wont have selfreferences and therefore no SOE
m
That will do 👍
l
but i'd still be interested (just for the heck of it): can an immutable self-reference exist ?
m
Sure, but not in a
data
class afaik.
hmm, let me test something
k
yes thats my understanding too, immutable self-reference not exists for data class
l
how is the fact that its a data class relevant here ?
if i remove the
data
keyword i still get the same error
m
Yeah but if its not a data class then you can do that:
Copy code
class Node {   
    val parent = this
}
But a data class constructor’s parameters must all be
val
, so they cannot use
this
since you’re in the constructor.
Or actually, before the constructor
Technically it should work because
this
is already known when the default value is evaluated.
It’s just not allowed
l
so that would be topic for language design then
m
yeah I think so
l
alright that concludes my questions, thanks guys
👍 1
k
you are welcome
m
For sake of completion. Without `data`:
Copy code
class Node private constructor(parent: Node?, foo: Unit) {

    val parent = parent ?: this


    constructor(parent: Node = useThis) :
            this(parent = parent.takeIf { it !== useThis }, foo = Unit)


    companion object {

        private val useThis = Node(parent = null, foo = Unit)
    }
}
l
Copy code
class Node(
	val author: String,
	val message: String,
	val children: List<Node>,
	parent: Node? = null
) {
	val parent = parent ?: this
}
wouldn't this suffice ?
m
You wanted it to be non-nullable 😄
l
well in the end
parent
is non-nullable which is was i was aiming for. to be fair, the parameter specifying the value of a non-nullable variable being nullable is a mess, but frankly so is your solution 😄
😁 1
anyway we're getting offtopic, i've decided to just use null as the roots parent