-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: spec: language: make slices of constant strings constant if the indexes are constant #28591
Comments
Marking as Go 2 because we've decided that all language changes are Go 2. I know that this has been discussed in the past but I don't remember why it wasn't changed. Maybe simply because it rarely comes up in practice. |
We should also consider accepting
|
It turns out that this proposed change is not backward-compatible after all ... Consider var _ = -"A"[0] we will get an error: -"A"[0] (constant -65 of type byte) overflows byte . This is currently (without the change) valid code. Oops! For similar reasons, constant index expressions are not backwards-compatible either. The length of a constant slice expression var _ uint = -uint(len("abc"[0:2])) (Without the change, these values are not constant, and the compiler won't complain.) Fun times! |
Would
be legal? |
@jimmyfrasche Very nice! Indeed it would. |
@griesemer FWIW, my most immediate reaction would be to suggest postponing this from Go 1.15 if that is indeed that case (for most of the reasons discussed in the related golang-dev thread, including your comment here). This change does not seem worth triggering the first use of the edit: sorry, mangled link. |
Change https://golang.org/cl/216977 mentions this issue: |
Change https://golang.org/cl/217119 mentions this issue: |
To the contrary! A minor, mostly-backward-compatible change seems like a great way to try out the mechanism without causing too much churn if it doesn't go as well as we expect. |
We discussed this issue in the proposal review committee. Since this proposal is not backward-compatible and we put a premium on language stability, we decided to not proceed with this for Go 1.15. We discussed introducing a vet check instead, but it doesn't seem warranted since this change is essentially language fine-tuning - a "nice to have" if it were backward-compatible, but not important. I will leave this open for future consideration, when non-backward compatible changes become viable due to universal use of modules. |
The degree to which a strict reading of backward compatibility leaves little room to maneuver is constantly surprising. |
One more case: _ = 1/len(""[:]) Currently it compiles, but if |
This was proposed for Go 1.15 (https://blog.golang.org/go1.15-proposals) but declined because it is not backwards compatible. Leaving open for some future breaking change (maybe). |
Another incompatible case: package main
const s = "Go101.org"
// len(s) == 9
// 1 << 9 == 512
// 512 / 128 == 4
var a byte = 1 << len(s) / 128
var b byte = 1 << len(s[:]) / 128
func main() {
println(a, b) // 4 0
} It will print |
@go101 That's diabolical. Spoiler: the difference arises from the top-down effect of the enclosing type (byte) on the shift operator when its right operand is non-constant. Thus |
Given the new extended forward compatibility mechanism, this breaking change could be implemented in files that set a sufficiently high minimum Go version. |
This will probably be assigned a Go2 label, although I think that it could be done during Go 1.
Consider multiline string constants:
If you feed this text to a parser and it finds a problem on the first line ("This is a long text"), it will actually report that the error is on the second line because of the leading newline. One might think that this is easily solved by slicing the string:
But this won't compile. The Spec currently says:
Why not make it constant? After all,
len(multiline)
is constant.There are other solutions to this. One could just use
multiline[1:]
everywhere where one doesn't want the leading newline. Or start "This is a long text" on the first line, but that hurts readability and "editability". Another solution is to makemultiline
a variable. The use case is pretty obscure and there isn't an immediate need for this, so this proposal is more about a question, why are slices (and indexing!) of constant strings not constant in the first place?The text was updated successfully, but these errors were encountered: