{"id":42812,"date":"2024-04-10T15:28:29","date_gmt":"2024-04-10T19:28:29","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=42812"},"modified":"2024-04-10T15:28:29","modified_gmt":"2024-04-10T19:28:29","slug":"run-time-polymorphism-in-swift","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2024\/04\/10\/run-time-polymorphism-in-swift\/","title":{"rendered":"Run-time Polymorphism in Swift"},"content":{"rendered":"<p><a href=\"https:\/\/belkadan.com\/blog\/2024\/04\/Run-time-Polymorphism-in-Swift\/\">Jordan Rose<\/a> (<a href=\"https:\/\/social.belkadan.com\/@jrose\/statuses\/01HTTGPPE74PER19E6ZAV19EES\">Mastodon<\/a>):<\/p>\n<blockquote cite=\"https:\/\/belkadan.com\/blog\/2024\/04\/Run-time-Polymorphism-in-Swift\/\">\n<p>There are only three ways to get run-time polymorphism in Swift. Well, three and a half.<\/p>\n<p>[&#8230;]<\/p>\n<ul>\n  <li><a href=\"https:\/\/belkadan.com\/blog\/2024\/04\/Run-time-Polymorphism-in-Swift\/#calling-a-function-value\">Calling a function value<\/a> (closure)<\/li>\n  <li><a href=\"https:\/\/belkadan.com\/blog\/2024\/04\/Run-time-Polymorphism-in-Swift\/#calling-a-class-member\">Calling a class member<\/a><\/li>\n  <li><a href=\"#https:\/\/belkadan.com\/blog\/2024\/04\/Run-time-Polymorphism-in-Swift\/calling-a-protocol-requirement\">Calling a protocol requirement<\/a><\/li>\n  <li><a href=\"https:\/\/belkadan.com\/blog\/2024\/04\/Run-time-Polymorphism-in-Swift\/#manually-testing-the-type-of-a-value\">Manually testing the type of a value<\/a><\/li>\n<\/ul>\n<p>[&#8230;]<\/p>\n<p>Generics are a powerful and flexible tool, but in general they don&rsquo;t result in any more run-time polymorphism than <code>any<\/code> types (formerly &ldquo;protocol composition types&rdquo;). This often throws people who are used to C++ templates, where overload resolution is done on the <em>concrete<\/em> type that satisfies the generic constraints rather than on the <em>generic<\/em> type. Swift didn&rsquo;t choose that option for two main reasons: it makes it much harder to diagnose issues at compile time, and it means that the entire body of the generic has to be visible to callers (so they can substitute in the concrete type). This is good for optimization, but bad for library evolution. You can think of Swift&rsquo;s model as &ldquo;the decision of which overload to call is made based on the knowledge where the call is written, which in this case is inside a generic function with certain constraints&rdquo;.<\/p>\n<\/blockquote>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2021\/12\/31\/the-surprising-cost-of-protocol-conformances-in-swift\/\">The Surprising Cost of Checking Protocol Conformances in Swift<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2015\/09\/01\/swift-protocols\/\">Swift Protocols<\/a><\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>Jordan Rose (Mastodon): There are only three ways to get run-time polymorphism in Swift. Well, three and a half. [&#8230;] Calling a function value (closure) Calling a class member Calling a protocol requirement Manually testing the type of a value [&#8230;] Generics are a powerful and flexible tool, but in general they don&rsquo;t result in [&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":"2024-04-10T19:28:32Z","apple_news_api_id":"eecc0fb8-2bd4-4d4f-8d13-cc0734a63e38","apple_news_api_modified_at":"2024-04-10T19:28:32Z","apple_news_api_revision":"AAAAAAAAAAD\/\/\/\/\/\/\/\/\/\/w==","apple_news_api_share_url":"https:\/\/apple.news\/A7swPuCvUTU-NE8wHNKY-OA","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":[326,46,54,71,901],"class_list":["post-42812","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-c-plus-plus","tag-languagedesign","tag-objective-c","tag-programming","tag-swift-programming-language"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/42812","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=42812"}],"version-history":[{"count":1,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/42812\/revisions"}],"predecessor-version":[{"id":42813,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/42812\/revisions\/42813"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=42812"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=42812"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=42812"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}