{"id":50832,"date":"2026-01-27T14:08:05","date_gmt":"2026-01-27T19:08:05","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=50832"},"modified":"2026-03-18T10:36:35","modified_gmt":"2026-03-18T14:36:35","slug":"swift-pitch-borrowing-sequence","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2026\/01\/27\/swift-pitch-borrowing-sequence\/","title":{"rendered":"Swift Pitch: Borrowing Sequence"},"content":{"rendered":"<p><a href=\"https:\/\/forums.swift.org\/t\/pitch-borrowing-sequence\/84332\">Ben Cohen<\/a>:<\/p>\n<blockquote cite=\"https:\/\/forums.swift.org\/t\/pitch-borrowing-sequence\/84332\">\n<p>A sequence provides access to its elements through an <code>Iterator<\/code>,\nand an iterator&rsquo;s <code>next()<\/code> operation <em>returns<\/em> an <code>Element?<\/code>.\nFor a sequence of noncopyable elements, this operation could only\nbe implemented by consuming the elements of the iterated sequence,\nwith the <code>for<\/code> loop taking ownership of the elements individually.<\/p>\n<p>While consuming iteration is sometimes what you want, <em>borrowing<\/em> iteration is\nequally important, serves as a better default for noncopyable elements,\nand yet cannot be supported by the existing <code>Sequence<\/code>.<\/p>\n<p>[&#8230;]<\/p>\n<p>Instead of offering up individual elements via <code>next()<\/code> as <code>IteratorProtocol<\/code> does,\n<code>BorrowingIteratorProtocol<\/code> offers up spans of elements. The iterator indicates there\nare no more elements to iterate by returning an empty <code>Span<\/code>.<\/p>\n<p>[&#8230;]<\/p>\n<p>Note that in the case of <code>Array<\/code>, the new protocol results in much less overhead\nfor the optimizer to eliminate. Iterating a <code>Span<\/code> in the inner loop is a lot\ncloser to the &ldquo;ideal&rdquo; model of advancing a pointer over a buffer and accessing\nthe elements directly. It is therefore expected that this design will result\nin better performance in some cases where today the optimizer is unable\nto eliminate the overhead of Swift&rsquo;s <code>Array<\/code>.<\/p>\n<p>[&#8230;]<\/p>\n<p>For this reason, it may not be appropriate to switch all <code>for<\/code> iteration to use\n<code>BorrowingSequence<\/code> when <code>Sequence<\/code> is available. How to determine which cases are\nbetter (such as <code>Array<\/code> is expected to be) and which are worse (such as the <code>UnfoldSequence<\/code>\nexample above) needs further investigation. [&#8230;] For now, if a <code>Sequence<\/code> conformance is available, it will be used\neven if <code>BorrowingSequence<\/code> is also available.<\/p>\n<\/blockquote>\n\n<p>I haven&rsquo;t had a need for noncopyable types, but I&rsquo;m interested in reducing ARC overhead when traversing objects. Most of the time I don&rsquo;t actually need to retain and release an object just to look at it briefly because I know that it&rsquo;s not going to be removed from the collection.<\/p>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2025\/10\/29\/swift-6-2\/\">Swift 6.2<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2025\/02\/17\/swift-proposal-inlinearray\/\">Swift Proposal: InlineArray<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2024\/03\/27\/noncopyable-generics-walkthrough\/\">Noncopyable Generics Walkthrough<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2023\/03\/22\/swift-proposal-noncopyable-structs-and-enums\/\">Swift Proposal: Noncopyable Structs and Enums<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2022\/08\/12\/swift-pitch-borrow-and-take-parameter-ownership-modifiers\/\">Swift Pitch: &ldquo;borrow&rdquo; and &ldquo;take&rdquo; Parameter Ownership Modifiers<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2022\/07\/01\/porting-graphing-calculator-from-c-to-swift\/\">Porting Graphing Calculator From C++ to Swift<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2022\/05\/26\/swift-_assemblyvision\/\">Swift @_assemblyVision<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2021\/12\/23\/roadmap-for-improving-swift-performance-predictability\/\">Roadmap for Improving Swift Performance Predictability<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2017\/02\/18\/swift-ownership-manifesto\/\">Swift Ownership Manifesto<\/a><\/li>\n<\/ul>\n\n<p id=\"swift-pitch-borrowing-sequence-update-2026-03-18\">Update (<a href=\"#swift-pitch-borrowing-sequence-update-2026-03-18\">2026-03-18<\/a>): <a href=\"https:\/\/github.com\/swiftlang\/swift-evolution\/blob\/main\/proposals\/0516-borrowing-sequence.md\">SE-0516<\/a>:<\/p>\n<blockquote cite=\"https:\/\/github.com\/swiftlang\/swift-evolution\/blob\/main\/proposals\/0516-borrowing-sequence.md\">\n<p>We propose a new protocol for iteration, <code>BorrowingSequence<\/code>, which\nwill work with noncopyable types and provide more efficient iteration\nin some circumstances for copyable types. The Swift compiler will\nsupport use of this protocol via the familiar <code>for<\/code>-<code>in<\/code> syntax.<\/p>\n<\/blockquote>","protected":false},"excerpt":{"rendered":"<p>Ben Cohen: A sequence provides access to its elements through an Iterator, and an iterator&rsquo;s next() operation returns an Element?. For a sequence of noncopyable elements, this operation could only be implemented by consuming the elements of the iterated sequence, with the for loop taking ownership of the elements individually. While consuming iteration is sometimes [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2026-01-27T19:08:08Z","apple_news_api_id":"91a64108-f028-4dc7-bb36-77cc2bfed0dc","apple_news_api_modified_at":"2026-03-18T14:36:38Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAAAA==","apple_news_api_share_url":"https:\/\/apple.news\/AkaZBCPAoTce7NnfMK_7Q3A","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[55,46,571,138,71,901],"class_list":["post-50832","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-arc","tag-languagedesign","tag-memory-management","tag-optimization","tag-programming","tag-swift-programming-language"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/50832","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=50832"}],"version-history":[{"count":2,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/50832\/revisions"}],"predecessor-version":[{"id":51274,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/50832\/revisions\/51274"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=50832"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=50832"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=50832"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}