benbjohnson/immutable

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

keep94 commented

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.