Skip to content

doc: please document the mean of "blk" #1327

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

Closed
bronze1man opened this issue Aug 3, 2018 · 8 comments
Closed

doc: please document the mean of "blk" #1327

bronze1man opened this issue Aug 3, 2018 · 8 comments
Labels
Milestone

Comments

@bronze1man
Copy link

bronze1man commented Aug 3, 2018

I have seen some code:

test "for else" {
    // For allows an else attached to it, the same as a while loop.
    var items = []?i32 { 3, 4, null, 5 };

    // For loops can also be used as expressions.
    var sum: i32 = 0;
    const result = for (items) |value| {
        if (value == null) {
            break 9;
        } else {
            sum += value.?;
        }
    } else blk: {
        assert(sum == 7);
        break :blk sum;
    };
}

What is blk mean in here? Why the break 9 do not have blk?

And the Grammar part do not have blk in it.

This is the biggest unknown for me.

@andrewrk andrewrk added the docs label Aug 3, 2018
@andrewrk andrewrk added this to the 0.3.0 milestone Aug 3, 2018
@andrewrk
Copy link
Member

andrewrk commented Aug 3, 2018

I'll leave this issue open until this answer is available in the official docs, but to answer your question:

break accepts an expression just like return. return returns the expression from the current function. break returns the expression from the current loop.

break also accepts an optional label, so that you can choose the loop or block you wish to return an expression from:

const result = this_is_a_label: {
    break :this_is_a_label i32(1234);
};
assert(result == 1234);

@bronze1man
Copy link
Author

bronze1man commented Aug 3, 2018

Here is my understanding:
The break can be a goto in c language.
It jump to the label and return the expression to that label.
It also can jump across several for or if.

@isaachier
Copy link
Contributor

@bronze1man you bring up a good point comparing break to goto. In fact, a number of languages do not support goto, like Zig itself, in order to avoid complex jumping in code. However, nested loops are one case where languages seem to be a bit more flexible. In Java, for example, goto is disallowed, but break can use a label argument (see https://docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html).

outer:
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < y; j++) {
            if (...) {
                break outer;
            }
        }
    }

I like that Zig builds on this concept by not only extending control flow in blocks, but allows the returning of values.

@thejoshwolfe
Copy link
Contributor

something that strikes me about the example code in the OP is that we maybe shouldn't allow loops to return values. You can accomplish that with block break statements, which i think is clearer anyway:

    const result = blk: for (items) |value| {
        if (value == null) {
            break :blk 9;
        } else {
            sum += value.?;
        }
    } else {
        assert(sum == 7);
        break :blk sum;
    };

@isaachier
Copy link
Contributor

@thejoshwolfe why not?

@andrewrk
Copy link
Member

@thejoshwolfe related to #1004

@raulgrell
Copy link
Contributor

What about the proposed result keyword? #732

    const val = for (items) |value| {
        if (value == null) {
            result 9;
        } else {
            sum += value.?;
        }
    } else {
        assert(sum == 7);
        result sum;
    };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants