I have this package:
https://pkg.go.dev/github.com/keep94/sqroot, which computes square roots to arbitrary precision. The Number type is a value type that represents a square root value. Early on it made sense to make Number be an immutable value type because it represents an immutable value such as sqrt(5).
However, now I want to add memoization to square root values. I have done this in a private branch, by adding a WithMemoize() method to Number that returns a new Number with memoization turned on. I have made the memoization multiple goroutine safe so that Number types still appear as immutable numerical values.
However, I am not sure that memoization works well with Value type semantics. For instance, if I have two Numbers, x and y, and I set y = x and continue to use x, y will see any future memoization done for x because I implement memoization with pointers behind the scenes. But, y = x implies that y gets a snapshot of x and won't see future changes in x. Moreover, I will never be able to add a method to Number that returns information about memoization progress because that would break immutability of the Number value type.
To solve this dilemma, I could change the API to be pointer based, by accepting and returning *Number instead of Number. Then I could say that Number does not support assignment directly. The advantage of using *Number is that if x and y are *Number and I set y = x, it is clear that whatever happens to x will happen to y because they point to the same instance. However, that would be a huge breaking change.
Any suggestions on what to do?