-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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: New labeled break syntax, removing colon prefix by reusing =>
token,
#5083
Comments
=>
token, =>
token,
=>
token, =>
token,
I personally have to think "where does the colon go again?" pretty much every time I write a labeled break. |
Food for thought: Odin's original idea for returning a value from a control construct was to use const val = {
give 32;
};
assert(val == 32); const val = blk: {
if (true) {
give blk 32;
}
}; Certainly though, the |
Right now only loop control has an anonymous label, then why not assign an anonymous label to assignment as well?
|
@iology I'm not sure I follow. |
@Tetralux No problem. I shouldn't say the assignment is labeled anonymously. :P I have just found out that
Sorry for the confusion! |
I have no idea whether this is feasible in zig, but I would suggest considering how Rust does this: the presence or absence of a semi-colon after the last expression in a block determines whether the block returns the value of the expression or not. |
@donaldcallen That was how Zig worked originally, but it was changed because it made it hard to tell the difference between a block returning the result of an if/while/for expression and a block with an if/while/for statement at the end. Here's the original issue. |
I see there are some (-1) reactions to this issue, but no explanations yet as to why it might be better to stick with status quo. |
How about we just make the colon consistent? const x = blk: {
y += 1;
break blk: y;
}
// or
const x = :blk {
y += 1;
break :blk y;
} |
Colon after the label would look strange when not breaking with a value: blk: {
y += 1;
break blk:;
} and colon before the label would look a bit strange for e.g. labeled loops: :outer while (true) {
while (true) {
break :outer;
}
} |
Edit: kindly ignore this. break; // normal
break value; // when returning a value from the current block
break #label; // when breaking a labeled block
break #label value; // when returning a value from labeled block
break #; // maybe
#label { ... break #label ... } // no colon required to label a block
# { ... break # [val]... } // allowed for conciseness (binds to innermost #) |
I sort of think of |
Worth noting that I fairly often get it the wrong way around, despite not being new to Zig. Perhaps we can just remove the colon from the break usage? const val = blk: {
break blk 31;
}; This cannot be confused with breaking with a single value, because there's two values given to Further, this also makes things more consistent, since, as an illustration: const Int = @IntType(32, false);
const i: Int = 40; // We don't have to specify `@` anywhere here, despite using `Int`!
// The name has been bound, and that's that. const val = blk: {
break blk 42; // We don't have to specify `:` anywhere here, despite using `blk`!
// The name has been bound, and that's that.
} So there's symmetry to be gained here. |
I like the look of that. We could also extend this to anonymous blocks (an equivalent to the const val = { // This could also be a `.: {` or a `: {` to indicate it can be broken with
// a non-void value, not sure.
break . 42; // `.` means "this specific block", or an equivalent "infer the nearest
// parent block".
};
std.testing.expect(val == 42); |
Was this proposal rejected? Are there any open proposals for a cleaner syntax to return values from blocks? I feel like the current syntax is really bad for readability in particular due to having to keep track of a label that might be declared dozens of lines away. I would really like to see this syntax changed to something that allows returning values without a superfluous label. |
New syntax, overview:
Pros:
=>
insteadblk: { ... }
orouter: while(...
stays as beforeswitch(cond) { true => 5, else => 10,};
Cons:
Example usage, taken from examples in the language reference:
The text was updated successfully, but these errors were encountered: