Skip to content

Commit

Permalink
Clarify the concept "Local Reasoning"
Browse files Browse the repository at this point in the history
  • Loading branch information
Joannis committed Mar 21, 2024
1 parent 4a5c0a0 commit 7adb38c
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 2 deletions.
Expand Up @@ -122,7 +122,7 @@ <h1>Structured Concurrency in Swift</h1><p>Swift 5.5 introduced structured concu
cache[url] = image
}
}
}</code></pre><p>The above example is non-trivial. It's not always obvious that you need to lock access to <code>image</code> twice. There are not one, but four traps here.</p><ol><li>It's easy to forget to lock access to the cache.</li><li>One might lock access to the cache, but omit either the check for an existing image - or the assignment of the image.</li><li>When locking access to the cache, one might forget to unlock the lock. When returning a value, as seen in the <code>image(for:)</code> function, the lock should be unlocked after accessing the value, but before returning.</li><li>Finally, when locking access to the cache, unlocking could be implemented only after the fetching has completed.</li></ol><p>These are all common mistakes, and they're hard to debug and reason about. This is where structured concurrency comes in.</p><p>Over the years, many patterns and abstractions have emerged to solve these problems. For example, the <code>Future</code> and <code>Promise</code> pattern is a common way to solve the problem of waiting for a value to be available. These abstractions are not part of the standard library, and are not always easy to work with or reason about. They're also not part of the standard library, leading to a fragmented ecosystem.</p><h2>Structured Concurrency</h2><p>Swift has always been focused on safety and maintainability. Common examples are a strong type system, the addition of <em>guard</em> statements, and checks that protect against integer overflows.</p><p>Similarly, Structured Concurrency is a language feature that is designed to write concurrent code that is more maintainable and easier to reason about. It's designed to solve these problems, and is the recommended to write concurrent code that is maintainable and easy to reason about.</p><p>You're probably familiar with structured programming, as it's a paradigm that every Swift developer uses. By making use of a <em>structured control flow</em> through constructs such as if-statements, for-loops and switch-statements, you're able to write code that is easy to reason about and maintain.</p><p>Structured Concurrency is the same concept, but applied to concurrent code. Functions in structured concurrency still have a clear entry and exit point. In Swift, this is done through the use of <code>async</code> functions and the <code>await</code> keyword.</p><h3>Async Functions</h3><p>An <code>async</code> function is a function that can pause and resume. Think of it as a function that can be split up into multiple parts.</p><p>When you order a pizza, you don't have to wait for the pizza to be made and delivered. You can continue watching your favourite show, while the pizza is delivered to your doorstep. Just like async functions. Should you need to know when the pizza is delivered, you can <code>await</code> the delivery.</p><pre><code class="language-swift"><span class="keyword">func</span> watchTelevision() <span class="keyword">async throws</span> {
}</code></pre><p>The above example is non-trivial. It's not always obvious that you need to lock access to <code>image</code> twice. There are not one, but four traps here.</p><ol><li>It's easy to forget to lock access to the cache.</li><li>One might lock access to the cache, but omit either the check for an existing image - or the assignment of the image.</li><li>When locking access to the cache, one might forget to unlock the lock. When returning a value, as seen in the <code>image(for:)</code> function, the lock should be unlocked after accessing the value, but before returning.</li><li>Finally, when locking access to the cache, unlocking could be implemented only after the fetching has completed.</li></ol><p>These are all common mistakes, and they're hard to debug and reason about. This is where structured concurrency comes in.</p><p>Over the years, many patterns and abstractions have emerged to solve these problems. For example, the <code>Future</code> and <code>Promise</code> pattern is a common way to solve the problem of waiting for a value to be available. These abstractions are not part of the standard library, and are not always easy to work with or reason about. They're also not part of the standard library, leading to a fragmented ecosystem.</p><h2>Structured Concurrency</h2><p>Swift has always been focused on safety and maintainability through <em>local reasoning</em>. Common examples are found in the type system, such as the use of value types. Because Array and Dictionary are value types, you can reason about them locally. You don't need to know about other parts of the code, and how those other parts might be modifying a reference to the same array or dictionary. Because value types are copied when passed around, you can reason about them locally.</p><p>Similarly, Structured Concurrency is a language feature that is designed to write concurrent code that is more maintainable and easier to reason about. It's designed to solve these problems, and is the recommended to write concurrent code that is maintainable and easy to reason about.</p><p>You're probably familiar with structured programming, as it's a paradigm that every Swift developer uses. By making use of a <em>structured control flow</em> through constructs such as if-statements, for-loops and switch-statements, you're able to write code that is easy to reason about and maintain.</p><p>Structured Concurrency is the same concept, but applied to concurrent code. Functions in structured concurrency still have a clear entry and exit point. In Swift, this is done through the use of <code>async</code> functions and the <code>await</code> keyword.</p><h3>Async Functions</h3><p>An <code>async</code> function is a function that can pause and resume. Think of it as a function that can be split up into multiple parts.</p><p>When you order a pizza, you don't have to wait for the pizza to be made and delivered. You can continue watching your favourite show, while the pizza is delivered to your doorstep. Just like async functions. Should you need to know when the pizza is delivered, you can <code>await</code> the delivery.</p><pre><code class="language-swift"><span class="keyword">func</span> watchTelevision() <span class="keyword">async throws</span> {
<span class="keyword">let</span> store = <span class="keyword">await</span> <span class="type">PizzaStore</span>.<span class="call">discover</span>()
<span class="keyword">let</span> pizza = <span class="keyword">await</span> store.<span class="call">orderPizza</span>()
<span class="keyword">let</span> show = <span class="call">startWatchingTV</span>()
Expand Down
Expand Up @@ -107,7 +107,7 @@ Over the years, many patterns and abstractions have emerged to solve these probl

## Structured Concurrency

Swift has always been focused on safety and maintainability. Common examples are a strong type system, the addition of _guard_ statements, and checks that protect against integer overflows.
Swift has always been focused on safety and maintainability through _local reasoning_. Common examples are found in the type system, such as the use of value types. Because Array and Dictionary are value types, you can reason about them locally. You don't need to know about other parts of the code, and how those other parts might be modifying a reference to the same array or dictionary. Because value types are copied when passed around, you can reason about them locally.

Similarly, Structured Concurrency is a language feature that is designed to write concurrent code that is more maintainable and easier to reason about. It's designed to solve these problems, and is the recommended to write concurrent code that is maintainable and easy to reason about.

Expand Down

0 comments on commit 7adb38c

Please sign in to comment.