<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:media="http://search.yahoo.com/mrss/"
>

<channel>
	<title>protocol &#8211; Wade Tregaskis</title>
	<atom:link href="https://wadetregaskis.com/tags/protocol/feed/" rel="self" type="application/rss+xml" />
	<link>https://wadetregaskis.com</link>
	<description></description>
	<lastBuildDate>Fri, 01 Mar 2024 19:55:35 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://wadetregaskis.com/wp-content/uploads/2016/03/Stitch-512x512-1-256x256.png</url>
	<title>protocol &#8211; Wade Tregaskis</title>
	<link>https://wadetregaskis.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">226351702</site>	<item>
		<title>Beware of specifying isolation requirements for whole protocols</title>
		<link>https://wadetregaskis.com/beware-of-specifying-isolation-requirements-for-whole-protocols/</link>
					<comments>https://wadetregaskis.com/beware-of-specifying-isolation-requirements-for-whole-protocols/#respond</comments>
		
		<dc:creator><![CDATA[]]></dc:creator>
		<pubDate>Fri, 01 Mar 2024 19:55:32 +0000</pubDate>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Actor]]></category>
		<category><![CDATA[isolation]]></category>
		<category><![CDATA[protocol]]></category>
		<category><![CDATA[Swift]]></category>
		<guid isPermaLink="false">https://wadetregaskis.com/?p=7829</guid>

					<description><![CDATA[Matt Massicotte has a well-written, brief introduction to isolation in Swift. But it mostly just enumerates the state of things, without offering much guidance. One pitfall in particular is important to call out, regarding isolated protocols. These might seem pretty similar &#8211; you&#8217;d be forgiven for assuming it&#8217;s just a convenience to put @MainActor on&#8230; <a class="read-more-link" href="https://wadetregaskis.com/beware-of-specifying-isolation-requirements-for-whole-protocols/" data-wpel-link="internal">Read more</a>]]></description>
										<content:encoded><![CDATA[
<p><a href="https://www.massicotte.org/about" data-wpel-link="external" target="_blank" rel="external noopener">Matt Massicotte</a> has <a href="https://www.massicotte.org/intro-to-isolation" data-wpel-link="external" target="_blank" rel="external noopener">a well-written, brief introduction to isolation in Swift</a>.  But it mostly just enumerates the state of things, without offering much guidance.  One pitfall in particular is important to call out, regarding isolated protocols.</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-disabled" data-code-block-pro-font-family="" style="font-size:.875rem;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #000000">@</span><span style="color: #001080">MainActor</span></span>
<span class="line"><span style="color: #001080">protocol</span><span style="color: #000000"> </span><span style="color: #001080">GloballyIsolatedProtocol</span><span style="color: #000000"> {</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">func</span><span style="color: #000000"> </span><span style="color: #795E26">method</span><span style="color: #000000">()</span></span>
<span class="line"><span style="color: #000000">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #001080">protocol</span><span style="color: #000000"> </span><span style="color: #001080">PerMemberIsolatedProtocol</span><span style="color: #000000"> {</span></span>
<span class="line"><span style="color: #000000">    @</span><span style="color: #001080">MainActor</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">func</span><span style="color: #000000"> </span><span style="color: #795E26">method</span><span style="color: #000000">()</span></span>
<span class="line"><span style="color: #000000">}</span></span></code></pre></div>



<p>These might seem pretty similar &#8211; you&#8217;d be forgiven for assuming it&#8217;s just a convenience to put <code>@MainActor</code> on the protocol overall rather than having to repeat it for every member of the protocol.  Less error-prone, too.</p>



<p>But, you generally shouldn&#8217;t do that.  They are <em>not</em> equivalent.</p>



<p>The first form is not merely saying that all the members of the protocol require a certain isolation, but that the <em>type</em> that conforms to the protocol must have that isolation.  The <em>whole</em> type.</p>



<p>And you might think:  …so what?</p>



<p>And indeed it <em>seems</em> like it&#8217;s fine:</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-disabled" data-code-block-pro-font-family="" style="font-size:.875rem;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #000000">@</span><span style="color: #001080">MainActor</span></span>
<span class="line"><span style="color: #001080">func</span><span style="color: #000000"> </span><span style="color: #795E26">doStuff</span><span style="color: #000000">() {}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #0000FF">class</span><span style="color: #000000"> </span><span style="color: #267F99">ClassA</span><span style="color: #000000">: </span><span style="color: #267F99">GloballyIsolatedProtocol</span><span style="color: #000000"> {</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">func</span><span style="color: #000000"> </span><span style="color: #795E26">method</span><span style="color: #000000">() {</span></span>
<span class="line"><span style="color: #000000">        </span><span style="color: #795E26">doStuff</span><span style="color: #000000">()</span></span>
<span class="line"><span style="color: #000000">    }</span></span>
<span class="line"><span style="color: #000000">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #0000FF">class</span><span style="color: #000000"> </span><span style="color: #267F99">ClassB</span><span style="color: #000000">: </span><span style="color: #267F99">PerMemberIsolatedProtocol</span><span style="color: #000000"> {</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">func</span><span style="color: #000000"> </span><span style="color: #795E26">method</span><span style="color: #000000">() {</span></span>
<span class="line"><span style="color: #000000">        </span><span style="color: #795E26">doStuff</span><span style="color: #000000">()</span></span>
<span class="line"><span style="color: #000000">    }</span></span>
<span class="line"><span style="color: #000000">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #008000">// ✅ Everything is hunky-dory as far as the compiler is concerned.</span></span></code></pre></div>



<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained">
<p>🤔 Some folks might think it&#8217;s a bit dangerously magical that <code>ClassA</code> is secretly <code>@MainActor</code> now by simply conforming to the protocol, even though nothing in the class&#8217;s declaration actually says that &#8211; and likewise for <code>method</code> for <code>ClassB</code>.  That&#8217;s largely a separate topic.  But okay, it makes a <em>kind</em> of sense at least…</p>
</div></div>



<p>But try to use actors instead of classes, and see how it all falls apart:</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-disabled" data-code-block-pro-font-family="" style="font-size:.875rem;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #001080">actor</span><span style="color: #000000"> ActorA: </span><span style="color: #001080">GloballyIsolatedProtocol</span><span style="color: #000000"> { </span><span style="color: #008000">// ❌ Actor &#39;ActorA&#39; cannot conform to global actor isolated protocol &#39;GloballyIsolatedProtocol&#39;</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">func</span><span style="color: #000000"> </span><span style="color: #795E26">method</span><span style="color: #000000">() {</span></span>
<span class="line"><span style="color: #000000">        </span><span style="color: #795E26">doStuff</span><span style="color: #000000">() </span><span style="color: #008000">// ❌ Call to main actor-isolated global function &#39;doStuff()&#39; in a synchronous actor-isolated context</span></span>
<span class="line"><span style="color: #000000">    }</span></span>
<span class="line"><span style="color: #000000">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #001080">actor</span><span style="color: #000000"> ActorB: </span><span style="color: #001080">PerMemberIsolatedProtocol</span><span style="color: #000000"> {</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">func</span><span style="color: #000000"> </span><span style="color: #795E26">method</span><span style="color: #000000">() { </span><span style="color: #008000">// ❌ Actor-isolated instance method &#39;method()&#39; cannot be used to satisfy main actor-isolated protocol requirement</span></span>
<span class="line"><span style="color: #000000">        </span><span style="color: #795E26">doStuff</span><span style="color: #000000">() </span><span style="color: #008000">// ❌ Call to main actor-isolated global function &#39;doStuff()&#39; in a synchronous actor-isolated context</span></span>
<span class="line"><span style="color: #000000">    }</span></span>
<span class="line"><span style="color: #000000">}</span></span></code></pre></div>



<p>All these error messages are correct, even if they may be surprising at first.  You might even say:  so what?  That&#8217;s working as expected.</p>



<p>The problem is that there is <em>nothing</em> an actor can do to conform to <code>GloballyIsolatedProtocol</code>.  It is an actor-hostile protocol.  It is <em>unusable</em> by actors.</p>



<p>Whereas <code>PerMemberIsolatedProtocol</code> <em>can</em> be used by an actor:</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-disabled" data-code-block-pro-font-family="" style="font-size:.875rem;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #001080">actor</span><span style="color: #000000"> ActorB: </span><span style="color: #001080">PerMemberIsolatedProtocol</span><span style="color: #000000"> {</span></span>
<span class="line"><span style="color: #000000">    @</span><span style="color: #001080">MainActor</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">func</span><span style="color: #000000"> </span><span style="color: #795E26">method</span><span style="color: #000000">() {</span></span>
<span class="line"><span style="color: #000000">        </span><span style="color: #795E26">doStuff</span><span style="color: #000000">()</span></span>
<span class="line"><span style="color: #000000">    }</span></span>
<span class="line"><span style="color: #000000">}</span></span></code></pre></div>



<p>Given that protocols are most often just used to express an interface requirement &#8211; e.g. for delegates, data sources, codability, etc &#8211; there is usually no reason why actors shouldn&#8217;t be allowed to conform to them.  Even if the protocol does have some isolation requirements, there&#8217;s no technical reason an actor can&#8217;t abide by those <em>if it&#8217;s given the chance</em>.</p>



<p>This leads into a more complicated aspect of isolation in Swift, regarding how actors aren&#8217;t necessarily restricted to their own isolation domain.  They can have methods and properties that are not isolated at all, or isolated to a <em>different</em> domain.  In Swift 6 they&#8217;ll even be able to have methods which are isolated <em>to different actors</em>!</p>



<p>So don&#8217;t make the mistake of assuming actors can only ever be off in their own isolated worlds.  And don&#8217;t needlessly exclude them from supporting your protocols.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wadetregaskis.com/beware-of-specifying-isolation-requirements-for-whole-protocols/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7829</post-id>	</item>
	</channel>
</rss>
