Consider changing immutable types such as List[T] and Map[T] to use by-value semantics instead of by-reference
keep94 opened this issue · 0 comments
I notice that List[T] and Map[T] use by-reference semantics whereas Set[T] uses by-value semantics. I propose that all the main immutable types in this package use by-value semantics like Set[T] already does. By-value semantics both imply and re-enforce immutability. If a method takes a pointer receiver, someone learning the API may wonder if the method somehow changes its receiver. But when a method takes a value receiver, this is a signal that the method doesn't change its receiver. Also by-reference semantics can't guarantee immutability. A client of an API could do something like this with pointers.
var t *SomeImmutableType
t = NewSomeImmutableType(...)
*t = SomeImmutableType{} // Oops, what t points to has unwittingly changed!
By-value semantics prevents this sort of API misuse and re-enforces immutability.
Note that using by-value sematics means that the type must fully support assignment. That is after b := a
b gets the value of a at that time. Later changes in a, don't get reflected in b and vice versa. Even with complicated data structures like trees and such, a developer can support full assignment using copy-on-write tricks.
Also it is helpful for immutable by-value types to support zero values. After a declaration like
var empty List[int]
empty
would be a fully usable empty list of ints.