# Const slices
## Proposal
Allows this sytax `const[]T` to create read-only slices.
`[]T` is ABI compatible with `const[]T`, that means:
- You can implicitely cast `[]T` to `const[]T`.
- Methods and Functions implementing `const[]T` also implements `[]T`.
- Function pointers of type `const[]T` also implements `[]T`.
Most importently you can implicitely cast `string` to `const[]byte`.
## Rational
This serve as a read-only (but not immutable) byte slice.
This is a commun ground that both `[]byte` and `string` types implement and would allows to skip copies when casting from either.
### Using strings as copy-on-write byte slices
In go we often use `string` not as to represent unicode text but just as a copy-on-write byte slice.
Even if we actually represent text, the context can change (for example feeding text to an encryption routine).
However many APIs working on binary data use `[]byte` types, even when they only read the data.
If our data is in `string` form we need to allocate a new array & copy the content to cast it into a `[]byte` because there is no ABI garentees that the function we call wont actually modify the content.
If thoses functions instead take `const[]byte`, the underlying execution is just copying a pointer and the length.
### `io.StringWriter`
This is a nice idea, but in most cases I found that not all my readers implements it, it also often just duplicating code from the equivalent `io.Writer` implementation.
This doesn't help with anything that not a writer. (like helper functions)
## Notes
`[]T` does not implement `const[]T`.
Reslicing a `const[]T` gives you a `const[]T`.
The only way to loose the constness is either to make a new non const slice and copy elements (example `append(nil, slice...)`) or by using `unsafe` (which would be unsafe as it might point to a `string`).
Many different functions in the `std` would need to be updated, as this is a mostly non breaking change I think it's fine ?
(Because of the one way ABI compatibility it's only breaking if someone use automatic type deduction to get the function we change and reassign a non const slice version, which is really easy to fix if that happen and hopefully rare.)
Breaking interfaces is harder, even ones that have thoses requirements said in docs (like `io.Reader`) it might be hard to ask people to change.
We can still make use of the `const` interface in relevent code (for example `(*strings.Reader).WriteTo`). So I think it's better to delay thoses changes giving time for people to switch their code to using `const[]byte` instead.
I only care about `const[]byte` I just think it would be weird if go was inconsistent and you couldn't also const other slices types.
If you think it's better only having `const[]byte`, that a fine change.
I don't know if calling `cap` passing a const slice should be an alias for `len` or a compile-time error.
## Examples where this applies
- `io.Writer` (I don't think we would update the actual `io.Writer` interface yet, but code that would benefit could do type assertion to upgrade to a const alternative)
- `encoding/hex` anything that encodes
- `encoding/binary` anything that read data
- ... It's gonna get repetitive if I continue.