-
Notifications
You must be signed in to change notification settings - Fork 4
Inconsistent position of 'const' between immutable targets of pointers and slices #16
Comments
It looks like the inconsistency has been noticed as the entries of the FAQ seem to use instead a syntax for immutability of slice elements that is consistent with immutability of pointer dereferencing. |
According to 2.8 Address Operators and 2.7 Slice Aliasing the results will be the following: var ints const [] const int = []{1, 2, 3}
ptr := &ints[0] // * const int
i := *ptr // const int
*ptr++ // Compile-time error
slc := ints[:1] // const [] const int
i = slc[0] // const int
slc[0]++ // Compile-time error |
Please consider closing this issue if you consider it resolved |
My point is not how to change the type of In 1.1.4, two var each2 = const [] const byte{'e', 'a', 'c', 'h'} In 1.2.1 this question is quite misleading:
v[0] = new(const T) The type of In 2.3, |
That's all correct. In fact, most of the examples including slices and maps in the document are wrong because I, coming from a C++ background, initially falsely assumed that With a var each2 = []byte{'e', 'a', 'c', 'h'} If immutability will be default behavior, or if not then: var each2 = immut []byte{'e', 'a', 'c', 'h'}
Wrong. Even though Having immutable composite types that don't protect their fields would make the entire concept useless similar to JavaScript I think I should describe contextual immutability better (or did I miss that point entirely?!). |
@merhalak // some absurdly complex type:
**[]map[int]*T This is a pointer to a pointer to a slice of maps of integers to pointers to T. It's much easier to read than any C/C++ equivalent. Mutability qualifiers should be no exception to this rule: // an even more absurd one:
mut * immut * mut [] immut map[mut int] mut * immut T This is a mutable pointer to an immutable pointer to a mutable slice of immutable maps of mutable integers to mutable pointers to immutable T. A mutability qualifier always affects the type(s) on the right and propagates until it's canceled out (MQP). Remember, those were just absurdly complicated examples, nobody will ever write things like this (people usually get hanged for doing so). You'll most likely see no more than: mut [] immut *T Which is a mutable slice of immutable pointers to immutable T (because immut propagates due to MQP). |
@romshark thanks for your explanation. Sorry for off topic. |
In Go, slices are just iterable pointers with safe bounds (safe thanks to runtime enforcement).
The type declaraction is consistent: the derefencing is on the left of the element type.
Here is some Go code that use mutability to indirectly modify the same memory location first through a pointer, then through a slice:
According to this proposal, to forbid modification through
*ptr
orslc[0]
(*ptr++
andslc[0]++
should be rejected at compile time), we have to declare like this:References:
I argue that the position of the
const
keyword in the type types expression are inconsistent: theconst
is on the right of*
but on the left of[]
.This is a follow-up of my tweets at https://twitter.com/omengue/status/1047743716461629440
The text was updated successfully, but these errors were encountered: