-
-
Notifications
You must be signed in to change notification settings - Fork 2.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
Allow re-declaring variables #14913
Comments
For some examples of my last point about blocks: // Currently
const x = a: {
var x_var: u32 = 3; // needs a different name because shadowing
x_var += 7;
break :a x_var;
};
// Proposed
var x: u32 = 3;
x += 7;
const x = x;
// Currently
const xy = a: {
var x: u32 = 3;
var y: u32 = 4;
y += x;
x += y;
break :a .{ .x = x, .y = y }; // Have to use a struct here because we can't break with two values
};
// Proposed
var x: u32 = 3;
var y: u32 = 4;
y += x;
x += y;
// No need for a struct because we can just `const`-ify the variables
const x = x;
const y = y; |
Case 1 is a good use case, and imo the best justification for this proposal. Case 2 is a bit problematic because of this:
I think blocks are a neater solution to this, and the "multiple variables" issue I hope can instead be resolved through tuple destructuring syntax. Case 3 is interesting - there's nothing immediately problematic about it as far as I can tell, but personally I quite like having to give the mutable variant a different name to make clear that it's distinct. Not sure how popular that opinion is however. |
I find Zig's shadowing rules kind of annoying, particularly in case (3), but I'm not sure allowing this form of redeclaration is the best answer because it then violates the very useful property that if you see a name declared const when reading code you know that it can never change. The property makes reasoning about code super useful.
fn foo(var x: u8, y: bool, var z: u8) { EDIT: actually I'm not sure how much I like this, as things then get confusing with pointers and Zig's semantics of how it transparently decides whether to pass by value vs. by reference |
I don't agree that it violates that property. A variable declared as I don't like |
Ahaha I literally though to add "(pedantically it is a new variable with the same name)" to my original reply, but I didn't think anyone would actually try to argue that. It is 100% a distinction without a difference IMO, it still absolutely violates the mental model of "when I see |
duplicate of rejected proposal #594 |
This doesn't seem like a duplicate of that; this doesn't allow arbitrary redeclaration, but only in specific cases where the actual value of the variable isn't changed. (I'm not sure whether I agree with all of it, but at least case 1 I think might be good.) |
I also don't see how this issue is related to #594, that seems to be proposing something very different. |
I acknowledge that this proposal is not a duplicate after all. However it is still rejected. |
Zig's shadowing rules (ie. "you can't") are excellent at avoiding bugs and aiding readability, with one exception: re-declaring variables. There are a few situations where you'd want to do this:
I propose that Zig relaxes its shadowing rules specifically for declarations of the form
{const,var} <x> = <x>
, ie. redeclaring a variable with no modifications.This would still prevent bugs where the wrong variable is accidentally modified due to eg. a local being renamed, and would aid readability by avoiding pointless extra names in cases like
pub const Thing = ThingArg
orvar foo = foo_const
.It would also reduce bugs caused by mutating a variable after it shouldn't be modified, which is currently not possible without using blocks (which can be pretty ugly and require extra names - and still doesn't work for cases where two variables need to be mutated at once and then
const
-ified).The text was updated successfully, but these errors were encountered: