# 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.