Skip to content

Control Flow Structures

Harneet provides a variety of control flow structures to direct the execution of your program.

Control Flow Rules

  1. If Conditions: Must evaluate to a truthy or falsy value
  2. Case Matching: Exact value equality (==) is used for case comparison
  3. Type Consistency: All cases in a switch must use the same data type
  4. Default Case: Optional catch-all for unmatched values
  5. Multi-Value Cases: Use comma-separated values: case 1, 2, 3 { }
  6. No Fall-through: Each case block executes independently (like Go, unlike C)

If-Else Statements

If-else statements allow you to execute code conditionally.

Basic If-Else

Basic If-Else
1
2
3
4
5
6
7
8
package main
import fmt
var x = 15
if x > 10 {
    fmt.Println("Greater than 10")
} else {
    fmt.Println("10 or less")
}

Else-If Chaining

Else-If Chaining
package main
import fmt
var score = 85
if score >= 90 {
    fmt.Println("Grade: A")
} else if score >= 80 {
    fmt.Println("Grade: B") 
} else if score >= 70 {
    fmt.Println("Grade: C")
} else if score >= 60 {
    fmt.Println("Grade: D")
} else {
    fmt.Println("Grade: F")
}

Switch Statements

Switch statements provide a way to execute different code blocks based on the value of an expression.

Use pattern matching

Though switches are present in Harneet, we urge you to use Pattern matching. Pattern matching is a safe way of creating conditional flows when compared to switches. See more here.

Supported Types in Switch

  • Integers: case 1, 2, 3 { ... }
  • Strings: case "hello", "world" { ... }
  • Mixed types not supported: Each switch statement must use consistent types

Integer Switch

Integer Switch
package main
import fmt
var day = 3
switch day {
case 1 {
    fmt.Println("Monday")
}
case 2 {
    fmt.Println("Tuesday")
}
case 3 {
    fmt.Println("Wednesday")
}
default {
    fmt.Println("Other day")
}
}

String Switch

String Switch
package main
import fmt
var name = "Alice"
switch name {
case "Bob" {
    fmt.Println("Hello Bob!")
}
case "Alice" {
    fmt.Println("Hello Alice!")
}
case "Charlie" {
    fmt.Println("Hello Charlie!")
}
default {
    fmt.Println("Hello stranger!")
}
}

Multi-Value Cases

Multi-Value Cases
package main
import fmt
var day = 6
switch day {
case 1 {
    fmt.Println("Monday")
}
case 2, 3 {
    fmt.Println("Tuesday or Wednesday")
}
case 4, 5 {
    fmt.Println("Thursday or Friday")
}
case 6, 7 {
    fmt.Println("Weekend")
}
default {
    fmt.Println("Invalid day")
}
}

For Loops

Harneet uses a single for construct (like Go) that covers multiple patterns:

  • C-style counted loop: for var i = 0; i < 10; i = i + 1 { ... }
  • Condition-only loop (while-style): for condition { ... }
  • For-in loops for iterables: Modern iteration with Python-like syntax
  • Range loops: for i in range(10) { ... }
  • Array iteration: for item in array { ... } or for i, item in array { ... }
  • Map iteration: for key in map { ... } or for key, value in map { ... }
  • Enumeration: for pair in enumerate(array) { ... }

There is no separate while keyword.

C-style For Loop

C-style For Loop
1
2
3
4
5
package main
import fmt
for var i = 0; i < 10; i = i + 1 {
    fmt.Println(i)
}

Condition-only For Loop (while-style)

Use a for with only a condition to loop while it remains true.

Condition-only For Loop
// Loop while the condition holds
package main
import fmt, collections
var i = 0
for i < 3 {
    fmt.Println("i:", i)
    i = i + 1
}

// Example: drain a queue
var q = collections.new_queue()
q.enqueue("a")
q.enqueue("b")

for !q.is_empty() {
    fmt.Println("dequeued:", q.dequeue())
}

For-in Loops

Harneet provides comprehensive for-in loop functionality for iterating over various data structures with Python-like syntax and Go-like performance.

Range Loops

Use range(n) to iterate over a sequence of numbers from 0 to n-1:

Range Loops
// Basic range loop
package main
import fmt
for i in range(5) {
    fmt.Printf("Number: %d\n", i)  // Prints 0, 1, 2, 3, 4
}

// Range with different variable name
for count in range(3) {
    fmt.Printf("Count: %d\n", count)
}

Array Iteration

Iterate over array elements with single or multiple variables:

Array Iteration
package main
import fmt
var fruits = ["apple", "banana", "cherry"]

// Single variable - iterate over elements
for fruit in fruits {
    fmt.Printf("Fruit: %s\n", fruit)
}

// Multiple variables - get index and element
for index, fruit in fruits {
    fmt.Printf("[%d] %s\n", index, fruit)
}

Map Iteration

Iterate over map keys or key-value pairs:

Map Iteration
package main
import fmt
var scores = {"Alice": 95, "Bob": 87, "Charlie": 92}

// Single variable - iterate over keys only
for name in scores {
    fmt.Printf("Name: %s\n", name)
}

// Multiple variables - iterate over key-value pairs
for name, score in scores {
    fmt.Printf("%s scored %d\n", name, score)
}

Enumeration with enumerate()

Use the enumerate() builtin function to get index-value pairs:

Enumeration with enumerate()
package main
import fmt
var colors = ["red", "green", "blue"]

// Using enumerate() function
for pair in enumerate(colors) {
    var index = pair[0]
    var color = pair[1]
    fmt.Printf("[%d] %s\n", index, color)
}

// Direct enumeration syntax (equivalent to above)
for index, color in colors {
    fmt.Printf("[%d] %s\n", index, color)
}

Nested Loops and Complex Data

For-in loops work with nested data structures:

Nested Loops and Complex Data
// Nested arrays
package main
import fmt
var matrix = [[1, 2], [3, 4], [5, 6]]
for row in matrix {
    fmt.Printf("Row: ")
    for cell in row {
        fmt.Printf("%d ", cell)
    }
    fmt.Println()
}

// Array of maps
var users = [
    {"name": "Alice", "age": 30},
    {"name": "Bob", "age": 25}
]

for user in users {
    fmt.Printf("User: %s (age %s)\n", user["name"], user["age"])
}

Break and Continue

Break and continue statements work in all for-in loop types:

Break and Continue
// Break example
package main
import fmt
for i in range(10) {
    if i == 5 {
        fmt.Printf("Breaking at %d\n", i)
        break
    }
    fmt.Printf("i = %d\n", i)
}

// Continue example  
for i in range(8) {
    if i % 2 == 0 {
        continue  // Skip even numbers
    }
    fmt.Printf("Odd number: %d\n", i)
}

Supported Iteration Patterns

Pattern Syntax Variables Bound Use Case
Range for i in range(n) i: integer Counting loops
Array Simple for item in array item: array element Processing items
Array Indexed for i, item in array i: index, item: element Need both index and value
Map Keys for key in map key: map key Processing keys only
Map Pairs for k, v in map k: key, v: value Processing key-value pairs
Enumerate for pair in enumerate(array) pair: [index, value] Manual index extraction