actor Main new create(env: Env) => env.out.print("Honk hjonk") let lots = true let x: I32 = 1 + if lots then 100 else 2 end // If the `then` and `else` branches of an `if` expression produce different types // then the `if` produces a union of the types produced by the `then` and `else // branches let friendly = false var y: (String | Bool) = if friendly then "Hello" else false end // If the `if` doesn't have an else, then the tested condition evaluating false // returns an implicit None. var z: (String | None) = if friendly then "Hello" end // (z is now None) // Loop expressions also return values // This one returns "Sarah" because it is the last expression in the list // If the loop had no iterations, then the value of the loop's `else` block // will be returned; if the loop has no `else` block then None will be returned var a: (String | None) = for name in ["Bob"; "Fred"; "Sarah"].values() do name end // I think this works like a `case` statement? match a | let s: String => env.out.print("a is " + s) | None => env.out.print("a is None") end // Pony `while` loops var count: U32 = 1 while count <= 10 do env.out.print(count.string()) count = count + 1 end // This `while` returns 10 (11 is the highest value reached by count, // but Pony assignments return the *old* value of the variable!) // You can stick an `else` on the `while` to cause it to return something other than // `None` if no iterations occur, as we saw above // You can `break` from loops in Pony, but since loops must return a value, the `break` // statement can also provide an expression to return. If the `break` does not provide // anything to return, the loop will fall through to returning the value from the `else` // block, or None, as usual. // This loop assigns "Jack" or "Jill" to name if that name is found (the first one found // is assigned), else "Herbert" var name = while false do // while moreNames() do var name' = "" // var name' = getName() if (name' == "Jack") or (name' == "Jill") then break name' end name' else "Herbert" end // Pony also has a `continue` keyword which skips iterations, like Python's. If the // final iteration of a loop is skipped, then the final return value will not be // calculated, so it cannot be returned -- in this case the value from the `else` // or None is used as before. // Pony `for` loops // Pony's `for` is like Python's `for` and not like C and C++'s `for` // For example, to iterate over an array and print its elements: for name' in ["Mike"; "Fred"; "Sarah"].values() do env.out.print(name') end // `for` loops take *iterators* after the `in` keyword. (This is why we call // .values() on the array instead of using it straight up.) // An iterator does not have to be any particular type, but it does need to // provide two particular methods: // has_next(): Bool // and // next(): T? // where T is the type of the objects in the collection over which the iterator // is iterating. // Pony uses structural typing internally, so if we want to create our own iterator // we don't have to declare that it provides any particular type // You can use `break` and `continue`, and `else`, with `for` loops just like with // `while` loops // Pony `repeat .. until` loops // oh wow Pony provides these? rare // They look like this: var counter = U64(1) repeat env.out.print("hello!!") counter = counter + 1 until counter > 7 end // You can use `break`, `continue` and `else` with these loops too