How do I migrate Swift control flow patterns to EK9?
← Control Flow · Ref: Q748
Swift developers coming to EK9 encounter five key control flow differences. Each has a direct EK9 equivalent.
SWIFT GUARD STATEMENT
Swift: guard let x = getValue() else { return nil } EK9: if x <- getValue() processX(x)
EK9 has no return statement. Instead of guard-else-return, put the success path inside the if block. For complex functions, decompose into smaller functions.
SWIFT SWITCH WITH WHERE CLAUSES
Swift: switch value { case .high where temp > 100: alert() case .low: monitor() } EK9: switch level case Level.High if temp > threshold alert() case Level.Low monitor()
EK9 switch cases use nested if for additional conditions.
SWIFT FOR-WHERE LOOPS
Swift: for item in items where item.isValid { process(item) } EK9: cat items | filter by isValid > stdout
Or with a for loop:
for item in items if item.isValid() process(item)
Swift's for-where is a convenience. EK9 stream pipelines express filtering naturally.
SWIFT DEFER
Swift: func process() { let file = open() defer { file.close() } use(file) } EK9: try -> resource <- openFile() use(resource) finally cleanup()
Or with try-with-resources for auto-close.
SWIFT REPEAT-WHILE
Swift: repeat { ... } while condition EK9: while condition ...
EK9 has no do-while loop. Use while with initialisation before the loop.
SWIFT FALLTHROUGH
Swift: switch x { case 1: fallthrough case 2: handle() } EK9: switch x case 1, 2 handle()
EK9 has no fallthrough. Use comma-separated case values instead.
See Q144 for the full control flow philosophy. See Q145 for break and continue replacements. See Q146 for function decomposition. See Q147 for switch fallthrough replacements. See Q148 for Java and Python migration. See Q135 for try/finally. See Q137 for try-with-resources. See Q747 for Swift optional binding migration.
Example
defines module qa.controlflow.swiftmigration defines type Level Low Medium High Critical defines function isValid() as pure -> item as String <- rtn as Boolean: item? <?- Maps a level to its response action. -?> responseAction() as pure -> level as Level <- action as String: switch level <- rtn as String: String() case Level.Low rtn: "monitor" case Level.Medium rtn: "investigate" case Level.High, Level.Critical rtn: "escalate" default rtn: "unknown" defines program SwiftControlFlowDemo() stdout <- Stdout() // === GUARD STATEMENT BECOMES IF GUARD === // Swift: guard let action = responseAction(.High) else { return } // EK9: success path inside the if block level <- Level.High action <- responseAction(level) if action? stdout.println(`Action for ${level}: ${action}`) // === SWITCH WITH CONDITIONS (replaces Swift where clause) === threshold <- Level.High for lvl in Level currentAction <- responseAction(lvl) if lvl >= threshold stdout.println(`ALERT: ${lvl} requires ${currentAction}`) else stdout.println(`OK: ${lvl} requires ${currentAction}`) // === FOR-WHERE BECOMES STREAM PIPELINE === // Swift: for item in items where item.isValid { process(item) } items <- ["alpha", String(), "beta", String(), "gamma"] cat items | filter by isValid > stdout // === COMMA-SEPARATED CASES (replaces Swift fallthrough) === // Swift: case .High: fallthrough; case .Critical: escalate() testLevel <- Level.Critical response <- switch testLevel <- rtn as String: String() case Level.Low, Level.Medium rtn: "routine" case Level.High, Level.Critical rtn: "emergency" default rtn: "unclassified" stdout.println(`${testLevel}: ${response}`)
Common mistakes
E01072 — EK9 has no return statement. Use if guard expressions for success paths. See ek9 -h E01072 for details.
Incorrect:
if action? stdout.println(`Action for ${level}: ${action}`) return
Correct:
if action? stdout.println(`Action for ${level}: ${action}`)
E50060 — String has no toString() method. responseAction() already returns a String. See ek9 -h E50060 for details.
Incorrect:
action <- responseAction(level).toString()
Correct:
action <- responseAction(level)
E50060 — Stream output target must be a stream sink, not a method call. Use > stdout to pipe output directly. See ek9 -h E50060 for details.
Incorrect:
cat items | filter by isValid > stdout.println()
Correct:
cat items | filter by isValid > stdout
Other ways to ask this
- What is the EK9 equivalent of Swift guard statement?
- How do I translate Swift switch with where clauses to EK9?
- How do I replace Swift for-where loops in EK9?
- How do I convert Swift defer to EK9?
Coming from another language?
Swift: guard-else for early exit, switch with where clauses and pattern matching, for-where filtered loops, defer for cleanup, repeat-while for do-while, fallthrough keyword in switch. Java: break, continue, return, switch fallthrough. Python: break, continue, return, no switch until match 3.10. Rust: break, continue, implicit return, match with guards. EK9: guard expressions (if x <- expr()), nested if for switch conditions, stream pipelines for filtered iteration, try/finally for cleanup, comma-separated case values for fallthrough.
Keywords: swift, while, fallthrough, defer, where, guard, repeat, pattern, migrate, flow, control, switch