Converting loops

Just leaving this here.

for var i = 0, j = 1; i < 5; i += 1, j = 1 << i, print("values", i, j) {
    print("2^\(i) is \(j)")
}

Is basically:

for <variable declarations>; <end condition test>; <updates> {
    <body>
}

Update: So why did I pick this loop in the first place? I googled around for the ugliest most complicated examples I could that involved multiple variables and side effects. I want to show that there’s a simple mechanical conversion, even for the crazy.

And you can change this to this:

do {
    <variable declarations>
    while <end condition test> {
        <body>
        <updates>
    }
}

Like this:

do {
    var i = 0, j = 1
    while i < 5 {
        print("2^\(i) is \(j)")
        i += 1; j = 1 << i; print("values", i, j)
    }
}

Or this, if you’d like to keep the original bits all together, you can use defer. Note that any early loop termination will still trigger the defer block.

do {
    <variable declarations>
    while <end condition test> {
        defer { <updates> }
        <body>
    }
}

Like this:

do {
    var i = 0, j = 1
    while i < 5 {
        defer { i += 1; j = 1 << i; print("values", i, j) }
        print("2^\(i) is \(j)")
    }
 }

And yes, you can still use break and continue

do {
    // Count to 49 by 2s
    var i = 0, j = 100
    while true {
        defer { i += 1; j -= 1 }
        if i % 2 == 0 { continue }
        if i >= j { break }
        print(i, terminator:" ")
    }
    print("")
}

And labels

 do {
    // count to 23 by 2s
    var i = 0, j = 100
    outer: while true {
        inner: while i < j {
            i += 1; j -= 1
            if i % 2 == 0 { continue inner } // same as continue
            print(i, terminator: " ")
            if i == 23 { break outer }
        }
    }
    print("")
}

One Comment

  • shouldn’t we all just be using tail call optimized recursive functions? 🙂