I agree with your sentiment. Const should really be the go to unless you plan on changing something. It makes longer code examples easier to read (I read a lot of convoluted error handling code at work and one of the best ways to clean it up is to declare existing stuff as const… immediately tells you what’s actually being changed).
It is fantastic that we get this help from the compiler to catch “sloppy” code.
But I also wish I could tell the compiler to let the sloppy code be “for now”. For example, when I am making quick changes and prototyping. I don’t mind being reminded I should clean it up at some point; I wish I could tell the compiler to “leave me alone” for now.
To potential repliers: please don’t cast this into a discussion about this sort of error being bad. I love having these errors. All I am saying is, I wish I could quiet them down while I am exploring my alternatives.
Your point about exploration is really interesting and it got me to thinking more about what this change implies.
It does make new users pay a heavier upfront fee in required learning… ya know, “don’t do x because x won’t compile due to y”. On the whole, I think this is a good change, but too much of it can quickly become constricting and incentivize people to do exploration elsewhere (like writing drafts in python instead of directly using the intended language itself).
There’s a fine line here. Back in ye olden times, programs could just stomp on the memory of another process. Sure, you had more freedom, but that also meant you had all the consequences of that freedom. Some people actually dislike type explicit languages entirely for this reason (it supposedly inhibits them from trying things).
I remember times when I have wanted to explore what I call “stupid changes” in my codebase – turn a whole thing off (which I know will break the algorithms) just to see if the impact on performance, or some other effect, is what I think it is. I usually do this in C with #if 0 / #endif blocks, which nest nicely. The point is, I know this is not the state of the code I want; I just want to see what happens. This is what I referred to as “exploration” above.
With this change (and related features, such as flagging parameters / variables when they are unused), and without the possibility of turning on this “sloppy mode” (temporarily making these errors into warnings, or hiding them), I find that sometimes this type of change percolates into a chain of useless changes, just because I wanted to see “what happens if…”.
One way of doing this would be adding a flag --sane or --strict that will not give you any room for shenanigans – error out on all unused parameters / variables, on vars that should be consts, etc. Maybe even let this be the default configuration, but have a way to turn it off.
From past discussions, it certainly seems that this will not happen. Oh well.
I’m afraid such a flag would be abused. The only mitigation I could think of is for the compiler to ask for a time-limited token, a-la Github personal access tokens, with this flag. But then again people would just write scripts and automate token generation and it’s not going to help at all…
I think we have different definitions / expectations of “abuse”, and how far the tooling should go to “protect from” / disable unwanted behaviour. If zig foo bar errors out on any of the things we have discussed here, how can it be abused? In this case, I am forced to write zig --sloppy foo bar if I want to opt into the sloppy mode.
The thing I am worried about is not somebody having an option to disable guardrails while playing in his/her sandbox, but that this option is going to be (ab)used “in production environment”. E.g. “we need this feature last week, no time to refactor, we’ll do it later”, etc.
And no, administrative measures (“don’t use --sloppy”!) don’t always work.
Isn’t that way of abuse already there with --autofix?
Honestly I think autofix is even worse than sloppy in that regard, since at least with sloppy we can get the errors back by removing the flag later.
Also “don’t use --sloppy in production” can be enforced by the project manager with CI, while --autofix usage cannot even be detected reliably.
In early days of Rust (before 1.0 release) there was lot of pressure to make borrow-checker optionally replace errors with warnings. But Rust team resisted and now memory safety guaranteed by borrow-checker is the Rust’s main selling point. Unconditionally barring sloppy code from compiling is a feature not a bug.
It can be enforced but it doesn’t necessarily have to be. Like I said, there are circumstances when you will be tempted (or outright pushed by the management) to skip the checks and just ship the next release already.