Chapter 72: Swift Functions
1. What is a function? (the most honest explanation)
A function is a named block of reusable code that:
- takes zero or more inputs (parameters)
- does some work
- optionally returns a result
Think of a function as a small helper inside your program:
- You tell it what you want (by passing arguments)
- It does its job
- It gives you back the answer (or nothing)
Functions are the most important building blocks of every non-trivial program.
2. The basic syntax — every form you will actually use
2.1 Simplest function — no parameters, no return
|
0 1 2 3 4 5 6 7 8 9 10 11 |
func sayHello() { print("Namaste, Hyderabad! 🌶️") } // Call it sayHello() // prints: Namaste, Hyderabad! 🌶️ |
2.2 Function with one parameter (very common)
|
0 1 2 3 4 5 6 7 8 9 10 11 |
func greet(name: String) { print("Namaste, \(name)! 👋") } greet(name: "Rahul") // Namaste, Rahul! 👋 greet(name: "Priya") // Namaste, Priya! 👋 |
Important rule: When calling a function, you must write the parameter label (name:) unless the label is hidden with _ (more later).
2.3 Function that returns a value
|
0 1 2 3 4 5 6 7 8 9 10 11 |
func add(_ a: Int, _ b: Int) -> Int { return a + b } let result = add(7, 8) // 15 print(result) |
Modern shorthand (very popular — no return keyword needed when body is single expression):
|
0 1 2 3 4 5 6 7 8 9 10 |
func multiply(_ a: Int, _ b: Int) -> Int { a * b // implicit return } print(multiply(6, 7)) // 42 |
Hidden parameter label (using _ — common when label would be redundant):
|
0 1 2 3 4 5 6 7 8 9 10 |
func greet(_ name: String) { print("Hello, \(name)!") } greet("Aarav") // No label when calling — clean |
3. Functions with multiple parameters — real patterns
3.1 Clear labels (most readable)
|
0 1 2 3 4 5 6 7 8 9 10 |
func introduce(name: String, age: Int, city: String) { print("\(name) is \(age) years old and lives in \(city).") } introduce(name: "Sneha", age: 24, city: "Hyderabad") |
3.2 Some labels hidden (very common style)
|
0 1 2 3 4 5 6 7 8 9 10 |
func greet(person name: String, from city: String) { print("Namaste \(name)! Greetings from \(city)!") } greet(person: "Rahul", from: "Bengaluru") |
→ person and from are external labels (shown when calling) → name and city are internal labels (used inside the function)
3.3 Default values (very common & powerful)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
func greet(name: String = "Guest", greeting: String = "Namaste") { print("\(greeting), \(name)! 👋") } greet() // Namaste, Guest! 👋 greet(name: "Priya") // Namaste, Priya! 👋 greet(greeting: "Hello") // Hello, Guest! 👋 greet(name: "Aarav", greeting: "Hi") // Hi, Aarav! 👋 |
4. Real-life examples — functions you will actually write
Example 1 — Format Indian currency (very frequent)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
func formatIndianCurrency(_ amount: Double) -> String { let formatter = NumberFormatter() formatter.numberStyle = .currency formatter.currencyCode = "INR" formatter.currencySymbol = "₹" formatter.maximumFractionDigits = 2 formatter.groupingSeparator = "," return formatter.string(from: NSNumber(value: amount)) ?? "₹0.00" } let price = 12499.99 print("Price: \(formatIndianCurrency(price))") // Price: ₹12,499.99 print("Discounted: \(formatIndianCurrency(12499.99 * 0.85))") // ₹10,624.99 |
Example 2 — Validate password (very common in forms)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
func isStrongPassword(_ password: String) -> Bool { guard !password.isEmpty else { return false } let hasMinLength = password.count >= 8 let hasUppercase = password.range(of: "[A-Z]", options: .regularExpression) != nil let hasLowercase = password.range(of: "[a-z]", options: .regularExpression) != nil let hasDigit = password.range(of: "[0-9]", options: .regularExpression) != nil let hasSpecial = password.range(of: "[!@#$%^&*()_+=]", options: .regularExpression) != nil return hasMinLength && hasUppercase && hasLowercase && hasDigit && hasSpecial } let tests = ["password", "Pass123!", "abc123", "StrongP@ssw0rd!"] for p in tests { print("'\(p)' → \(isStrongPassword(p) ? "strong" : "weak")") } |
Example 3 — Calculate final price with tax & discount (business logic)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
func calculateFinalPrice( basePrice: Double, quantity: Int = 1, discountPercent: Double = 0, taxRate: Double = 0.18 ) -> Double { let subtotal = basePrice * Double(quantity) let discountAmount = subtotal * (discountPercent / 100) let priceAfterDiscount = subtotal - discountAmount let taxAmount = priceAfterDiscount * taxRate return priceAfterDiscount + taxAmount } let final = calculateFinalPrice( basePrice: 1499.99, quantity: 2, discountPercent: 10 ) print("Final amount: ₹\(String(format: "%.2f", final))") |
Example 4 — Filter active users (social / admin apps)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
struct User { let id: Int let name: String let isActive: Bool let lastActive: Date? } func activeUserNames(from users: [User], since daysAgo: Int = 30) -> [String] { let cutoff = Date().addingTimeInterval(-Double(daysAgo * 24 * 60 * 60)) return users .filter { $0.isActive || ($0.lastActive ?? .distantPast) >= cutoff } .map { $0.name } } let users = [ User(id: 1, name: "Rahul", isActive: true, lastActive: nil), User(id: 2, name: "Priya", isActive: false, lastActive: Date().addingTimeInterval(-15*24*60*60)), User(id: 3, name: "Aarav", isActive: false, lastActive: Date().addingTimeInterval(-45*24*60*60)) ] let active = activeUserNames(from: users) print("Active users:", active) |
5. Very Common Beginner Mistakes & Correct Habits
| Mistake | Wrong / Risky code | Correct / Better habit | Why? |
|---|---|---|---|
| Forgetting to return value | func add(a: Int, b: Int) -> Int { a + b } | return a + b or implicit return | Compile error if missing |
| Using var for parameters | func greet(var name: String) { … } | Parameters are let by default — good! | Prevents accidental mutation |
| Force-unwrapping in functions | func getName(user: User?) -> String { user!.name } | guard let user else { return “Guest” } | Safer, better error handling |
| Too many parameters | func createUser(name, age, city, email, phone, …) | Use struct / DTO instead | More readable, easier to extend |
| Side-effects in pure functions | func calculateTotal(price: Double) -> Double { print(“Calculating…”); return price * 1.18 } | Keep functions pure when possible | Easier to test, predict |
6. Quick Reference — Function patterns you will use most
| Goal | Most idiomatic style | Notes / Tip |
|---|---|---|
| Simple action (no return) | func log(message: String) { print(message) } | Side-effect functions |
| Pure calculation | func add(_ a: Int, _ b: Int) -> Int { a + b } | Implicit return, no return keyword |
| Optional return | func findUser(id: Int) -> User? { … } | Return nil when not found |
| Multiple outputs | func divide(_ a: Double, by b: Double) -> (quotient: Double, remainder: Double) | Use tuple or custom struct |
| Default parameters | func greet(name: String = “Guest”) { … } | Very common for optional arguments |
| Throwing function | func loadData() throws -> Data { … } | Use try, do-catch when calling |
7. Small Practice – Try these
- Write a function greetUser(name: String, age: Int) that prints: “Namaste [name]! You are [age] years old.”
- Write a function calculateDiscountedPrice(original: Double, discountPercent: Double = 10) -> Double
- Write a function isStrongPassword(_ password: String) -> Bool that checks:
- length ≥ 8
- has at least one uppercase
- has at least one number
Paste your code here if you want feedback or want to see even cleaner versions!
What would you like to explore next?
- Functions with default parameters & variadic parameters (…)
- Throwing functions (throws, try, do-catch)
- Function types & closures (very important)
- Nested functions & higher-order functions
- Functions in SwiftUI (action closures, view builders)
- Or move to another topic (optionals, arrays, switch, loops…)
Just tell me — we’ll continue in the same clear, detailed, patient style 😊
