{"id":2736,"date":"2026-02-05T11:55:29","date_gmt":"2026-02-05T11:55:29","guid":{"rendered":"https:\/\/demo.materiamedica.net\/demo6\/?p=2736"},"modified":"2026-02-05T11:55:29","modified_gmt":"2026-02-05T11:55:29","slug":"chapter-75-swift-closures","status":"publish","type":"post","link":"https:\/\/demo.materiamedica.net\/demo6\/chapter-75-swift-closures\/","title":{"rendered":"Chapter 75: Swift Closures"},"content":{"rendered":"<h3 dir=\"auto\">1. What is a closure? (the most honest, intuitive explanation)<\/h3>\n<p dir=\"auto\">A <strong>closure<\/strong> is <strong>a function without a name<\/strong> that can:<\/p>\n<ul dir=\"auto\">\n<li>capture variables from the surrounding scope (even after that scope ends)<\/li>\n<li>be passed around like any other value<\/li>\n<li>be stored in variables, arrays, dictionaries\u2026<\/li>\n<li>be called later<\/li>\n<\/ul>\n<p dir=\"auto\">In simple words:<\/p>\n<blockquote dir=\"auto\">\n<p dir=\"auto\">A closure is an <strong>anonymous function<\/strong> that remembers the environment where it was created.<\/p>\n<\/blockquote>\n<p dir=\"auto\">Think of a closure as a <strong>small portable worker<\/strong> that:<\/p>\n<ul dir=\"auto\">\n<li>Knows its <strong>instructions<\/strong> (the code inside {})<\/li>\n<li>Remembers <strong>who hired it and what tools it was given<\/strong> (captured variables)<\/li>\n<li>Can be <strong>sent to another department<\/strong> (passed as parameter)<\/li>\n<li>Can be <strong>called much later<\/strong> (even after the original room is closed)<\/li>\n<\/ul>\n<h3 dir=\"auto\">2. The basic syntax \u2014 every form you will actually see<\/h3>\n<h4 dir=\"auto\">2.1 Simplest closure \u2014 no parameters, no return<\/h4>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>let sayHello = {\r\n    print(\"Namaste, Hyderabad! \ud83c\udf36\ufe0f\")\r\n}\r\n\r\nsayHello()          \/\/ Namaste, Hyderabad! \ud83c\udf36\ufe0f<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h4 dir=\"auto\">2.2 Closure with parameters &amp; return value<\/h4>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>let add = { (a: Int, b: Int) -&gt; Int in\r\n    return a + b\r\n}\r\n\r\nprint(add(7, 8))     \/\/ 15<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\"><strong>Shorthand syntax<\/strong> (very common &amp; clean):<\/p>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>let multiply = { $0 * $1 }      \/\/ implicit parameters $0, $1\r\nprint(multiply(6, 7))           \/\/ 42\r\n\r\nlet greet = { name in\r\n    print(\"Namaste, \\(name)! \ud83d\udc4b\")\r\n}\r\n\r\ngreet(\"Rahul\")                  \/\/ Namaste, Rahul! \ud83d\udc4b<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h4 dir=\"auto\">2.3 Trailing closure syntax (the most beautiful &amp; most used style)<\/h4>\n<p dir=\"auto\">When the <strong>last parameter<\/strong> of a function is a closure, Swift lets you write it <strong>outside<\/strong> the parentheses \u2014 very clean.<\/p>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>\/\/ Without trailing closure\r\narray.forEach( { item in\r\n    print(item)\r\n} )\r\n\r\n\/\/ With trailing closure \u2014 much more readable\r\narray.forEach { item in\r\n    print(item)\r\n}\r\n\r\n\/\/ Even shorter with implicit $0\r\narray.forEach {\r\n    print($0)\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\"><strong>You will see trailing closures everywhere<\/strong> in SwiftUI, Combine, animations, networking, etc.<\/p>\n<h3 dir=\"auto\">3. Capturing values \u2014 the real superpower of closures<\/h3>\n<p dir=\"auto\">Closures can <strong>remember<\/strong> variables from the surrounding scope \u2014 even after that scope disappears.<\/p>\n<p dir=\"auto\">This is called <strong>capturing<\/strong> or <strong>closing over<\/strong> variables.<\/p>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>func makeCounter() -&gt; () -&gt; Int {\r\n    var count = 0\r\n    \r\n    let increment = {\r\n        count += 1      \/\/ \u2190 captures &amp; modifies count\r\n        return count\r\n    }\r\n    \r\n    return increment\r\n}\r\n\r\nlet counter1 = makeCounter()\r\nlet counter2 = makeCounter()\r\n\r\nprint(counter1())   \/\/ 1\r\nprint(counter1())   \/\/ 2\r\nprint(counter1())   \/\/ 3\r\n\r\nprint(counter2())   \/\/ 1  \u2190 separate counter<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\"><strong>Real-life analogy<\/strong>:<\/p>\n<p dir=\"auto\">Think of a counter function as a <strong>ticket machine<\/strong> at a parking lot. Each time you call makeCounter(), you get a <strong>new independent machine<\/strong> \u2014 each remembers its own ticket count.<\/p>\n<p dir=\"auto\">This is why closures are so powerful for:<\/p>\n<ul dir=\"auto\">\n<li>callbacks<\/li>\n<li>completion handlers<\/li>\n<li>stateful operations<\/li>\n<li>event handlers<\/li>\n<\/ul>\n<h3 dir=\"auto\">4. Real-life examples \u2014 closures you will actually write every day<\/h3>\n<h4 dir=\"auto\">Example 1 \u2013 Completion handler (networking, animations, alerts)<\/h4>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>func fetchUser(id: Int, completion: @escaping (String?, Error?) -&gt; Void) {\r\n    \/\/ pretend network delay\r\n    DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {\r\n        if id == 1 {\r\n            completion(\"Rahul\", nil)\r\n        } else {\r\n            completion(nil, NSError(domain: \"User\", code: 404))\r\n        }\r\n    }\r\n}\r\n\r\n\/\/ Usage \u2014 trailing closure style (very common)\r\nfetchUser(id: 1) { name, error in\r\n    if let name {\r\n        print(\"User: \\(name)\")\r\n    } else if let error {\r\n        print(\"Error: \\(error.localizedDescription)\")\r\n    }\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h4 dir=\"auto\">Example 2 \u2013 Sorting with custom comparator (very frequent)<\/h4>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>struct Product {\r\n    let name: String\r\n    let price: Double\r\n}\r\n\r\nlet products = [\r\n    Product(name: \"Earbuds Pro\", price: 24999),\r\n    Product(name: \"Phone Case\",  price: 999),\r\n    Product(name: \"Charger\",     price: 2499),\r\n    Product(name: \"Earbuds\",     price: 9999)\r\n]\r\n\r\n\/\/ Sort by price ascending, then name alphabetical\r\nlet sorted = products.sorted { a, b in\r\n    if a.price != b.price {\r\n        return a.price &lt; b.price\r\n    }\r\n    return a.name &lt; b.name\r\n}\r\n\r\n\/\/ Trailing closure style (very clean)\r\nproducts.forEach {\r\n    print(\"\u20b9\\($0.price) \u2013 \\($0.name)\")\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h4 dir=\"auto\">Example 3 \u2013 SwiftUI button action (very common)<\/h4>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>Button(\"Tap me\") {\r\n    print(\"Button tapped!\")\r\n}\r\n\r\n\/\/ with parameters\r\nButton(action: {\r\n    print(\"Complex action\")\r\n    saveData()\r\n    showConfirmation()\r\n}) {\r\n    Text(\"Save\")\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h4 dir=\"auto\">Example 4 \u2013 Animation completion (very typical in SwiftUI\/UIKit)<\/h4>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>UIView.animate(withDuration: 0.5) {\r\n    view.alpha = 0\r\n} completion: { finished in\r\n    if finished {\r\n        view.removeFromSuperview()\r\n        print(\"Animation completed\")\r\n    }\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">5. Very Common Beginner Mistakes &amp; Correct Habits<\/h3>\n<div>\n<div dir=\"auto\">\n<table dir=\"auto\">\n<thead>\n<tr>\n<th data-col-size=\"lg\">Mistake<\/th>\n<th data-col-size=\"lg\">Wrong \/ Dangerous code<\/th>\n<th data-col-size=\"md\">Correct \/ Better habit<\/th>\n<th data-col-size=\"xl\">Why?<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td data-col-size=\"lg\">Forgetting @escaping on completion handlers<\/td>\n<td data-col-size=\"lg\">func fetch(completion: (String) -&gt; Void)<\/td>\n<td data-col-size=\"md\">func fetch(completion: @escaping (String) -&gt; Void)<\/td>\n<td data-col-size=\"xl\">Without @escaping you get compile error when storing the closure<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Strong reference cycles (memory leak)<\/td>\n<td data-col-size=\"lg\">self.button.action = { self.doSomething() }<\/td>\n<td data-col-size=\"md\">Use [weak self] or [unowned self]<\/td>\n<td data-col-size=\"xl\">Retain cycle \u2014 view controller never deallocates<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Using var inside closure when not needed<\/td>\n<td data-col-size=\"lg\">var count = 0; closure = { count += 1 }<\/td>\n<td data-col-size=\"md\">let count = 0 if not changing<\/td>\n<td data-col-size=\"xl\">let is safer<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Long closure body without trailing syntax<\/td>\n<td data-col-size=\"lg\">array.map({ item in \u2026 })<\/td>\n<td data-col-size=\"md\">array.map { item in \u2026 }<\/td>\n<td data-col-size=\"xl\">Trailing closure is much more readable<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Mutating captured variable without var<\/td>\n<td data-col-size=\"lg\">let counter = 0; increment = { counter += 1 }<\/td>\n<td data-col-size=\"md\">var counter = 0<\/td>\n<td data-col-size=\"xl\">Compile error \u2014 captured let cannot be mutated<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div><\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">6. Quick Summary \u2014 Closure patterns you will use every day<\/h3>\n<div>\n<div dir=\"auto\">\n<table dir=\"auto\">\n<thead>\n<tr>\n<th data-col-size=\"lg\">Goal<\/th>\n<th data-col-size=\"xl\">Most idiomatic code<\/th>\n<th data-col-size=\"md\">Notes \/ Tip<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td data-col-size=\"lg\">Simple completion handler<\/td>\n<td data-col-size=\"xl\">fetch { result in \u2026 }<\/td>\n<td data-col-size=\"md\">Trailing closure style<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Capture self safely<\/td>\n<td data-col-size=\"xl\">{ [weak self] in self?.doSomething() }<\/td>\n<td data-col-size=\"md\">Prevents retain cycles<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Sort with custom logic<\/td>\n<td data-col-size=\"xl\">sorted { $0.price &lt; $1.price }<\/td>\n<td data-col-size=\"md\">Very common<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Animation \/ alert completion<\/td>\n<td data-col-size=\"xl\">animate { \u2026 } completion: { finished in \u2026 }<\/td>\n<td data-col-size=\"md\">Trailing closure is standard<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Map \/ filter \/ reduce chains<\/td>\n<td data-col-size=\"xl\">array.filter { $0 &gt; 10 }.map { $0 * 2 }<\/td>\n<td data-col-size=\"md\">Functional style \u2014 very idiomatic<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div><\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">7. Small Practice \u2013 Try these<\/h3>\n<ol dir=\"auto\">\n<li>Create a function greetPeople(_ names: [String], greeting: String = &#8220;Namaste&#8221;) that uses forEach to print &#8220;Namaste, Rahul!&#8221; for each name.<\/li>\n<li>Write a closure that calculates discount: let applyDiscount = { (price: Double, percent: Double) -&gt; Double in price * (1 &#8211; percent\/100) }<\/li>\n<li>Create a retry function using closure: func retry(times: Int, delay: Double, operation: @escaping () -&gt; Bool)<\/li>\n<\/ol>\n<p dir=\"auto\">Paste your code here if you want feedback or want to see even cleaner versions!<\/p>\n<p dir=\"auto\">What would you like to explore next?<\/p>\n<ul dir=\"auto\">\n<li><strong>@escaping<\/strong> closures in depth<\/li>\n<li><strong>Capturing<\/strong> values \u2014 strong, weak, unowned<\/li>\n<li><strong>Trailing closures<\/strong> in SwiftUI &amp; Combine<\/li>\n<li><strong>Closure as function parameter<\/strong> vs <strong>function type<\/strong><\/li>\n<li><strong>Escaping vs non-escaping<\/strong> closures<\/li>\n<li>Or move to another topic (optionals, arrays, switch, protocols\u2026)<\/li>\n<\/ul>\n<p dir=\"auto\">Just tell me \u2014 we\u2019ll continue in the same clear, patient, detailed style \ud83d\ude0a<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. What is a closure? (the most honest, intuitive explanation) A closure is a function without a name that can: capture variables from the surrounding scope (even after that scope ends) be passed around&#46;&#46;&#46;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[76],"tags":[],"class_list":["post-2736","post","type-post","status-publish","format-standard","hentry","category-swift"],"_links":{"self":[{"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts\/2736","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/comments?post=2736"}],"version-history":[{"count":1,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts\/2736\/revisions"}],"predecessor-version":[{"id":2737,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts\/2736\/revisions\/2737"}],"wp:attachment":[{"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/media?parent=2736"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/categories?post=2736"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/tags?post=2736"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}