{"id":12821,"date":"2026-09-30T14:20:00","date_gmt":"2026-09-30T11:20:00","guid":{"rendered":"https:\/\/handoli.com\/index.php\/2026\/09\/30\/using-swifts-some-keyword-beyond-swiftui\/"},"modified":"2026-09-30T14:20:00","modified_gmt":"2026-09-30T11:20:00","slug":"using-swifts-some-keyword-beyond-swiftui","status":"publish","type":"post","link":"https:\/\/handoli.com\/index.php\/2026\/09\/30\/using-swifts-some-keyword-beyond-swiftui\/","title":{"rendered":"Using Swift\u2019s \u2018some\u2019 keyword beyond SwiftUI"},"content":{"rendered":"<p>Developers who have worked with Apple\u2019s SwiftUI framework have likely encountered the <code>some<\/code> keyword in the context of defining custom views, where it\u2019s typically used to enable the generic <code>View<\/code> protocol to be referenced as a type when declaring a view\u2019s <code>body<\/code>:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">struct<\/span> ContentView: <span class=\"s-type\">View<\/span> {\n    <span class=\"s-keyword\">var<\/span> body: <span class=\"s-keyword\">some<\/span> <span class=\"s-type\">View<\/span> {\n        <span class=\"s-type\">Text<\/span>(<span class=\"s-string\">\"Hello, world!\"<\/span>)\n            .<span class=\"s-call\">padding<\/span>()\n            .<span class=\"s-call\">foregroundStyle<\/span>(.<span class=\"s-dotAccess\">blue<\/span>)\n            .<span class=\"s-call\">font<\/span>(.<span class=\"s-dotAccess\">headline<\/span>)\n    }\n}<\/code><\/pre>\n<p>When using the <code>some<\/code> keyword, the compiler will infer the underlying concrete type that\u2019s actually being returned, which is especially helpful when working with APIs that heavily utilize generics \u2014 such as SwiftUI. Without <code>some<\/code>, we\u2019d have to always manually specify the concrete type of our entire view hierarchy, which even in the case of the above (very simple) <code>ContentView<\/code> is as complex as this:<\/p>\n<pre class=\"splash\"><code><span class=\"s-type\">ModifiedContent<\/span>&lt;<span class=\"s-type\">ModifiedContent<\/span>&lt;<span class=\"s-type\">ModifiedContent<\/span>&lt;<span class=\"s-type\">Text<\/span>,\n<span class=\"s-type\">_PaddingLayout<\/span>&gt;, <span class=\"s-type\">_ForegroundStyleModifier<\/span>&lt;<span class=\"s-type\">Color<\/span>&gt;&gt;,\n<span class=\"s-type\">_EnvironmentKeyWritingModifier<\/span>&lt;<span class=\"s-type\">Optional<\/span>&lt;<span class=\"s-type\">Font<\/span>&gt;&gt;&gt;<\/code><\/pre>\n<p>But the <code>some<\/code> keyword isn\u2019t <em>just<\/em> useful when working with SwiftUI. In fact, we can use it to solve similar generics-based problems, and as syntactic sugar, across a wide range of use cases.<\/p>\n<h2>Generic function parameters<\/h2>\n<p>Let\u2019s say that we\u2019re working on a video watching app, and that our app\u2019s <code>Database<\/code> type contains an API for saving a set of videos to the user\u2019s <em>\u201cwatch later\u201d<\/em> list:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">actor<\/span> Database {\n    ...\n\n    <span class=\"s-keyword\">func<\/span> saveToWatchLater(<span class=\"s-keyword\">_<\/span> videos: [<span class=\"s-type\">Video<\/span>]) {\n        <span class=\"s-keyword\">var<\/span> watchLater = <span class=\"s-call\">loadWatchLater<\/span>()\n\n        <span class=\"s-keyword\">for<\/span> video <span class=\"s-keyword\">in<\/span> videos {\n            watchLater.<span class=\"s-call\">addVideo<\/span>(withID: video.<span class=\"s-property\">id<\/span>)\n        }\n\n        <span class=\"s-call\">save<\/span>(watchLater)\n    }\n}<\/code><\/pre>\n<p>Currently, our API only accepts arrays of <code>Video<\/code> values, but across our app, videos might be stored using different kinds of collections \u2014 including sets, dictionaries, and perhaps custom collections\/sequences as well. So, to make our <code>saveToWatchLater<\/code> API a bit more <em>generic<\/em> we could, well, actually make it generic:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">actor<\/span> Database {\n    ...\n\n    <span class=\"s-keyword\">func<\/span> saveToWatchLater&lt;T: <span class=\"s-type\">Sequence<\/span>&gt;(<span class=\"s-keyword\">_<\/span> videos: <span class=\"s-type\">T<\/span>) <span class=\"s-keyword\">where<\/span> <span class=\"s-type\">T<\/span>.<span class=\"s-type\">Element<\/span> == <span class=\"s-type\">Video<\/span> {\n        ...\n    }\n}<\/code><\/pre>\n<p>That works, but it does arguably add a bit of complexity to our function declaration. This is where the <code>some<\/code> keyword comes in, which \u2014 just like when using SwiftUI \u2014 can help us avoid some of the complexity involved in working with generics. In this case, we can use it to be able to reference the <code>Sequence<\/code> protocol directly, which works since that protocol marks its associated <code>Element<\/code> type as its <em>primary associated type<\/em>.<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">actor<\/span> Database {\n    ...\n\n    <span class=\"s-keyword\">func<\/span> saveToWatchLater(<span class=\"s-keyword\">_<\/span> videos: <span class=\"s-keyword\">some<\/span> <span class=\"s-type\">Sequence<\/span>&lt;<span class=\"s-type\">Video<\/span>&gt;) {\n        ...\n    }\n}<\/code><\/pre>\n<p>With that, we\u2019ve ended up with a quite simple solution that still lets us leverage the power and flexibility that generics offer, all without introducing any kind of type erasure or runtime overhead.<\/p>\n<h2>An alternative to type erasure or boxing<\/h2>\n<p>Speaking of type erasure, the <code>some<\/code> keyword can also help us avoid having to perform type erasure, or otherwise box a given value or object into something that needs to be resolved at runtime (which tends to add both complexity and overhead).<\/p>\n<p>For example, let\u2019s say that we\u2019re structuring various async operations across our app using an <code>Operation<\/code> protocol, which in turn emits <code>OperationEvent<\/code> values when performed \u2014 sort of like a lightweight, less complex version of something like a Combine publisher:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">enum<\/span> OperationEvent&lt;Output&gt; {\n    <span class=\"s-keyword\">case<\/span> progressUpdate(completionRatio: <span class=\"s-type\">Double<\/span>)\n    <span class=\"s-keyword\">case<\/span> finished(<span class=\"s-type\">Output<\/span>)\n    <span class=\"s-keyword\">case<\/span> failed(<span class=\"s-type\">Error<\/span>)\n}\n\n<span class=\"s-keyword\">protocol<\/span> Operation&lt;Output&gt; {\n    <span class=\"s-keyword\">associatedtype<\/span> Output\n    <span class=\"s-keyword\">typealias<\/span> EventStream = <span class=\"s-type\">AsyncStream<\/span>&lt;<span class=\"s-type\">OperationEvent<\/span>&lt;<span class=\"s-type\">Output<\/span>&gt;&gt;\n\n    <span class=\"s-keyword\">func<\/span> perform() -&gt; <span class=\"s-type\">EventStream<\/span>\n}<\/code><\/pre>\n<blockquote>\n<p>Our <code>Operation<\/code> protocol declares its <code>Output<\/code> type as its primary associated type, using the same syntax as concrete types use when declaring their generic type lists.<\/p>\n<\/blockquote>\n<p>One way of using the above protocol, for example in order to implement upload and download networking operations, would be to have our various APIs return concrete, <code>Operation<\/code>-conforming types that\u2019ll become known to each call site:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">actor<\/span> NetworkService {\n    ...\n\n    <span class=\"s-keyword\">func<\/span> downloadOperation(for url: <span class=\"s-type\">URL<\/span>) -&gt; <span class=\"s-type\">DownloadOperation<\/span> {\n        <span class=\"s-type\">DownloadOperation<\/span>(url: url, service: <span class=\"s-keyword\">self<\/span>)\n    }\n\n    <span class=\"s-keyword\">func<\/span> uploadOperation(for upload: <span class=\"s-type\">Upload<\/span>) -&gt; <span class=\"s-type\">UploadOperation<\/span> {\n        <span class=\"s-type\">UploadOperation<\/span>(upload: upload, service: <span class=\"s-keyword\">self<\/span>)\n    }\n}<\/code><\/pre>\n<p>The above works, but it does arguably expose a bit too many implementation details to the caller. For example, if the above <code>NetworkService<\/code> would be part of a Swift Package\u2019s public API, then we\u2019d have to also make all return types (such as <code>DownloadOperation<\/code> and <code>UploadOperation<\/code>) public as well, which we might not want to do.<\/p>\n<p>Ideally, we might want to make all operation implementations private, which would give our <code>NetworkService<\/code> a much simpler and clearer API design, for example using a setup like this:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">private extension<\/span> <span class=\"s-type\">NetworkService<\/span> {\n    <span class=\"s-keyword\">struct<\/span> DownloadOperation: <span class=\"s-type\">Operation<\/span>&lt;<span class=\"s-type\">Data<\/span>&gt; {\n        <span class=\"s-keyword\">var<\/span> url: <span class=\"s-type\">URL<\/span>\n        <span class=\"s-keyword\">var<\/span> service: <span class=\"s-type\">NetworkService<\/span>\n\n        <span class=\"s-keyword\">func<\/span> perform() -&gt; <span class=\"s-type\">EventStream<\/span> {\n            ...\n        }\n    }\n\n    <span class=\"s-keyword\">struct<\/span> UploadOperation: <span class=\"s-type\">Operation<\/span>&lt;<span class=\"s-type\">Void<\/span>&gt; {\n        <span class=\"s-keyword\">var<\/span> upload: <span class=\"s-type\">Upload<\/span>\n        <span class=\"s-keyword\">var<\/span> service: <span class=\"s-type\">NetworkService<\/span>\n\n        <span class=\"s-keyword\">func<\/span> perform() -&gt; <span class=\"s-type\">EventStream<\/span> {\n            ...\n        }\n    }\n}<\/code><\/pre>\n<p>However, the above change does present us with a problem \u2014 what are we supposed to return from our various operation-building functions? This is a case where, historically, type erasure has often been used, to enable us to return an opaque wrapper that boxes our underlying implementation\u2019s actual logic. In this case, we could make such a wrapper capture the underlying type\u2019s <code>perform<\/code> method as a closure:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">struct<\/span> AnyOperation&lt;Output&gt;: <span class=\"s-type\">Operation<\/span>&lt;<span class=\"s-type\">Output<\/span>&gt; {\n    <span class=\"s-keyword\">var<\/span> performer: () -&gt; <span class=\"s-type\">EventStream<\/span>\n\n    <span class=\"s-keyword\">func<\/span> perform() -&gt; <span class=\"s-type\">EventStream<\/span> {\n        <span class=\"s-call\">performer<\/span>()\n    }\n}\n\n<span class=\"s-keyword\">actor<\/span> NetworkService {\n    ...\n\n    <span class=\"s-keyword\">func<\/span> downloadOperation(for url: <span class=\"s-type\">URL<\/span>) -&gt; <span class=\"s-type\">AnyOperation<\/span>&lt;<span class=\"s-type\">Data<\/span>&gt; {\n        <span class=\"s-keyword\">let<\/span> operation = <span class=\"s-type\">DownloadOperation<\/span>(url: url, service: <span class=\"s-keyword\">self<\/span>)\n        <span class=\"s-keyword\">return<\/span> <span class=\"s-type\">AnyOperation<\/span>(performer: operation.<span class=\"s-property\">perform<\/span>)\n    }\n\n    <span class=\"s-keyword\">func<\/span> uploadOperation(for upload: <span class=\"s-type\">Upload<\/span>) -&gt; <span class=\"s-type\">AnyOperation<\/span>&lt;<span class=\"s-type\">Void<\/span>&gt; {\n        <span class=\"s-keyword\">let<\/span> operation = <span class=\"s-type\">UploadOperation<\/span>(upload: upload, service: <span class=\"s-keyword\">self<\/span>)\n        <span class=\"s-keyword\">return<\/span> <span class=\"s-type\">AnyOperation<\/span>(performer: operation.<span class=\"s-property\">perform<\/span>)\n    }\n}<\/code><\/pre>\n<p>This is another case where the <code>some<\/code> keyword can really help us simplify things. Instead of having to manually do type erasure, we can achieve the same kind of separation of concerns and clean API design simply by having each of our operation-building functions return <code>some Operation<\/code>, specialized with the type of value that each operation produces \u2014 like this:<\/p>\n<pre class=\"splash\"><code><span class=\"s-keyword\">actor<\/span> NetworkService {\n    ...\n\n    <span class=\"s-keyword\">func<\/span> downloadOperation(for url: <span class=\"s-type\">URL<\/span>) -&gt; <span class=\"s-keyword\">some<\/span> <span class=\"s-type\">Operation<\/span>&lt;<span class=\"s-type\">Data<\/span>&gt; {\n        <span class=\"s-type\">DownloadOperation<\/span>(url: url, service: <span class=\"s-keyword\">self<\/span>)\n    }\n\n    <span class=\"s-keyword\">func<\/span> uploadOperation(for upload: <span class=\"s-type\">Upload<\/span>) -&gt; <span class=\"s-keyword\">some<\/span> <span class=\"s-type\">Operation<\/span>&lt;<span class=\"s-type\">Void<\/span>&gt; {\n        <span class=\"s-type\">UploadOperation<\/span>(upload: upload, service: <span class=\"s-keyword\">self<\/span>)\n    }\n}<\/code><\/pre>\n<p>Much simpler, and again, without introducing additional runtime overhead, since types annotated with the <code>some<\/code> keyword are always resolved at compile time. That\u2019s one of the key differences between this solution compared to if we instead would\u2019ve chosen to use the <code>any<\/code> keyword, which also lets us refer to a generic protocol as a type, but with the important difference that it boxes the underlying value into a so-called <em>existential<\/em>, which needs to be unboxed and resolved at runtime.<\/p>\n<p>That of course doesn\u2019t mean that the <code>any<\/code> keyword is just a worse version of <code>some<\/code> \u2014 existentials have their use cases too, which we\u2019ll take a closer look at in future articles.<\/p>\n<h2>Conclusion<\/h2>\n<p>When certain Swift features are prominently used within a specific framework or domain, it can be easy to think of such a feature as just a tool for that specific task \u2014 as is often the case with the <code>some<\/code> keyword and SwiftUI. But hopefully this article has illustrated that <code>some<\/code> is an incredibly useful feature that can be used to reduce complexity when working with all sorts of generics, and to create very neat APIs that cleanly abstract their implementation details from their call sites. All without sacrificing performance or introducing additional runtime logic.<\/p>\n<p>Thanks for reading!<\/p>","protected":false},"excerpt":{"rendered":"<p>Developers who have worked with Apple\u2019s SwiftUI framework have likely encountered the some keyword in the context of defining custom views, where it\u2019s typically used to enable the generic View protocol to be referenced as a type when declaring a view\u2019s body: struct ContentView: View { var body: some View { Text(&#8220;Hello, world!&#8221;) .padding() .foregroundStyle(.blue) [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"rop_custom_images_group":[],"rop_custom_messages_group":[],"rop_publish_now":"initial","rop_publish_now_accounts":[],"rop_publish_now_history":[],"rop_publish_now_status":"pending","footnotes":""},"categories":[1],"tags":[],"class_list":["post-12821","post","type-post","status-publish","format-standard","hentry","category-explore"],"_links":{"self":[{"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/posts\/12821","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/comments?post=12821"}],"version-history":[{"count":0,"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/posts\/12821\/revisions"}],"wp:attachment":[{"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/media?parent=12821"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/categories?post=12821"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/handoli.com\/index.php\/wp-json\/wp\/v2\/tags?post=12821"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}