The ".fixed" notation looks really some weird at the beginning.
But I think it is an acceptable design.
It is best design for it I have found up to now.
Surely, it would be better if an alternative better design will be found.
The ".fixed" suffixes are always the last part of a type literal.
For example, "[]*T.fixed" always means "([]*T).fixed".
"[]*(T.fixed)" and "[](*T.fixed)" are both invalid interpretation.
The interpretation rule is the same for expressions.
No, finals are not variables. Finals are the opposites of variables.
A value is either a variable or a final.
Currently, there are already some final values in Go, including declared function/method
values and all kinds of intermediate results, such as function returns,
operator operation evaluation results, explicit value conversion results, etc.
Maybe it is ok to view constants as a subset of finals.
I would admit this proposal is a combination of the proposals
This proposal provides an organic solution to compromise the two.
The current descriptions of the "about final, fixed, and immutable values"
section of this proposal is still not perfect. I will update it in a few hours as
the following shows
"variable/final" and "normal/fixed" are two properties of a value,
they corresponds "self_modifiable" and "ref_modifiable".
A value is either a variable or a final.
A value is either fixed or normal.
Please note, although a value can't be modified through fixed values
which are referencing it, it is possible to be modified through other
normal values which are referencing it. From the view of a fixed
value, all values referenced by it are final and fixed values.
A fixed value itself may be modifiable it is not a final.
Values referenced by a final may be modifiable if the final is not fixed.
Data synchronizations might be still needed when concurrently reading
a final value. But if the final value isn't referenced by any normal value,
then concurrently reading it doesn't need data synchronization.
In particular, all declared finals satisfy this requirement.
Yes, the two points are both true.
For the second point, I would say this is more a feature than a problem.
And in fact, this proposal really support some true immutable values.
As above has mentioned, a final values without being referenced by
any normal values is a true immutable value. For example,
if we declared a variable as "var v = []int{1, 2, 3}.fixed", then the
elements of v are immutable. There are not (safe) ways to modify them.
For the fixed-poisoning problem, it is really hard to avoid.
The main intention of the fixed value concept is to support
read-only parameters and result. By change the parameters
of a function to fixed, the corresponding parameters of all other functions
called by this functionand passed with the fixed input parameter as arguments
also need to be changed to fixed.
However we can introducing fixed parameters eventually
(if this proposal is proved to be good). For example, we can firstly
modify the prototype of fmt.Print function as func (...interface{}.fixed).
No user code needs to be modified. It is just the parameter types of
several functions in the standard packages are needed to be changed.
BTW, this proposal really has a problem, it may cause "bytes.TrimXXX"
function to be split into several versions for normal and fixed arguments.
This needs the generics feature to be fixed.
So this proposal depends on the future generics feature to fully work.