{"data":{"post":{"title":"Swift Macro: Revisited - Traps and Pitfalls","subtitle":"","isPublished":true,"createdTime":"2023-08-10T00:00:00.000Z","lastModifiedTime":null,"license":null,"tags":["Swift","Macro"],"category":"Programming","file":{"childMdx":{"excerpt":"In the previous post, we learned the strengths and the essence that\nuniquely define the Swift Macro…","code":{"body":"function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nconst layoutProps = {};\nreturn class MDXContent extends React.Component {\n  constructor(props) {\n    super(props);\n    this.layout = null;\n  }\n\n  render() {\n    const _this$props = this.props,\n          {\n      components\n    } = _this$props,\n          props = _objectWithoutProperties(_this$props, [\"components\"]);\n\n    return React.createElement(MDXTag, {\n      name: \"wrapper\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `In the previous post, we learned the strengths and the essence that\nuniquely define the Swift Macro. The examples in that post work so far so\ngood. However, can we be confident and bold, implementing any Swift macros\nwe want now?`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `No.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `The features that bring Swift Macro advantages also introduce traps and\npitfalls that could shoot the programmers themselves in the foot. In this\npost, I would like to show you several ones that I've found and how to\novercome them.`), React.createElement(MDXTag, {\n      name: \"h2\",\n      components: components\n    }, `Traps and Pitfalls`), React.createElement(MDXTag, {\n      name: \"h3\",\n      components: components\n    }, `Potential Chaos in Control Flow`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `The `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `#unwrap`), ` example in the previous post shows that Swift Macro\nexpansion could involve `, React.createElement(MDXTag, {\n      name: \"strong\",\n      components: components,\n      parentName: \"p\"\n    }, `control flow manipulation`), ` and\n`, React.createElement(MDXTag, {\n      name: \"strong\",\n      components: components,\n      parentName: \"p\"\n    }, `lexical scope sharing`), `:`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Before expansion:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `func foo(_ bar: Int?) {\n  #unwrap(bar) {\n    print(bar)\n  }\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `After expansion:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `func foo(_ bar: Int?) {\n  // #unwrap expansion began\n  guard let bar = bar else {\n    return\n  }\n  print(bar)\n  // #unwrap expansion ended\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Since the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `return`), ` statement in the macro expansion which manipulates the\ncontrol flow is an intentional behavior, this would not make us surprised.\nBut what if we put this macro in a loop? Here is an example:`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Before expansion:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `func foo(_ bar: Int?) {\n  for _ in 0..<10 {\n    #unwrap(bar) {\n      print(bar)\n    }\n  }\n  // Rest codes\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `After expansion:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `func foo(_ bar: Int?) {\n  for _ in 0..<10 {\n    // #unwrap expansion began\n    guard let bar = bar else {\n      return\n    }\n    print(bar)\n    // #unwrap expansion ended\n  }\n  // Rest codes\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `From the macro expansion shown above, we can learn that if we pass a `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `nil`), `\nto `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `foo`), `, the rest codes after the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `for`), ` loop would not be executed. This\nis because the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `return`), ` statement involved by the macro expansion would\nbreak the outer loop.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `However, the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `#unwrap`), ` macro's name only conveys the purpose of unwrapping\noptional values. This might cause the programmer who uses this macro to\nthink that returning from the applied site is an\n`, React.createElement(MDXTag, {\n      name: \"strong\",\n      components: components,\n      parentName: \"p\"\n    }, `unintentional behavior`), `.`), React.createElement(MDXTag, {\n      name: \"h3\",\n      components: components\n    }, `Name Conflicts in Freestanding Macros`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `The odd mentioned above is not the only potential pitfall in the expansion\nthat I gave for the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `#unwrap`), ` macro. One more pitfall here is that\nexpanding the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `#unwarp`), ` macro may cuase variable redeclarations. Let's\ncontinue to examine that macro expansion:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `func foo(_ bar: Int?) {\n  // #unwrap expansion began\n  guard let bar = bar else {\n    return\n  }\n  print(bar)\n  // #unwrap expansion ended\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `This brought variable name shadowing where the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `guard let bar: Int`), `\nshadows the argument `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `_ bar: Int?`), `. In the case of `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `#unwrap`), `, the variable\nname shadowing is trivial because it is an intentional behavior. However,\nsince freestanding Swift macro expansions involve lexical scope sharing\nwith the applied site, this could turn variable name shadowing into\nvariable redeclaration in the expansions of naïvely implemented macros.\nHere is a contrived example, the variable name `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `updater`), ` is shadowed\nbefore the macro expansion but redeclared after the expansion:`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Before expansion:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `func foo(_ bar: Int?) {\n  let updater = Updater()\n  #unwrap(bar) {\n    let updater = Updater()\n    print(bar)\n    updater.update()\n  }\n  print(updater.description)\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `After expansion:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `func foo(_ bar: Int?) {\n  // \\`updater\\` defined the first time\n  let updater = Updater()\n  // #unwrap expansion began\n  guard let bar else {\n    return\n  }\n  // \\`updater\\` defined the second time\n  let updater = Updater()\n  print(bar)\n  updater.update()\n  // #unwrap expansion ended\n  print(updater.description)\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `With a clean build in Xcode, you could find this example could not be\ncompiled:`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"figure\",\n      components: components,\n      parentName: \"p\"\n    }, `\n    `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"figure\",\n      props: {\n        \"href\": \"/static/4f67b11a38fb483fa19b34ea24fdb1fa/08d94/compilation-failure-variable-redeclaration-expanding-unwrap.webp\"\n      }\n    }, React.createElement(MDXTag, {\n      name: \"picture\",\n      components: components,\n      parentName: \"a\"\n    }, `\n  `, React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/4f67b11a38fb483fa19b34ea24fdb1fa/0cc25/compilation-failure-variable-redeclaration-expanding-unwrap.png\",\n        \"srcSet\": [\"/static/4f67b11a38fb483fa19b34ea24fdb1fa/5116e/compilation-failure-variable-redeclaration-expanding-unwrap.png 178w\", \"/static/4f67b11a38fb483fa19b34ea24fdb1fa/92f55/compilation-failure-variable-redeclaration-expanding-unwrap.png 356w\", \"/static/4f67b11a38fb483fa19b34ea24fdb1fa/0cc25/compilation-failure-variable-redeclaration-expanding-unwrap.png 712w\", \"/static/4f67b11a38fb483fa19b34ea24fdb1fa/7ae06/compilation-failure-variable-redeclaration-expanding-unwrap.png 1068w\", \"/static/4f67b11a38fb483fa19b34ea24fdb1fa/eee47/compilation-failure-variable-redeclaration-expanding-unwrap.png 1424w\", \"/static/4f67b11a38fb483fa19b34ea24fdb1fa/38407/compilation-failure-variable-redeclaration-expanding-unwrap.png 2136w\", \"/static/4f67b11a38fb483fa19b34ea24fdb1fa/240a0/compilation-failure-variable-redeclaration-expanding-unwrap.png 2144w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/4f67b11a38fb483fa19b34ea24fdb1fa/690c8/compilation-failure-variable-redeclaration-expanding-unwrap.webp\",\n        \"srcSet\": [\"/static/4f67b11a38fb483fa19b34ea24fdb1fa/25c8a/compilation-failure-variable-redeclaration-expanding-unwrap.webp 178w\", \"/static/4f67b11a38fb483fa19b34ea24fdb1fa/60698/compilation-failure-variable-redeclaration-expanding-unwrap.webp 356w\", \"/static/4f67b11a38fb483fa19b34ea24fdb1fa/690c8/compilation-failure-variable-redeclaration-expanding-unwrap.webp 712w\", \"/static/4f67b11a38fb483fa19b34ea24fdb1fa/d7e52/compilation-failure-variable-redeclaration-expanding-unwrap.webp 1068w\", \"/static/4f67b11a38fb483fa19b34ea24fdb1fa/456ef/compilation-failure-variable-redeclaration-expanding-unwrap.webp 1424w\", \"/static/4f67b11a38fb483fa19b34ea24fdb1fa/2a654/compilation-failure-variable-redeclaration-expanding-unwrap.webp 2136w\", \"/static/4f67b11a38fb483fa19b34ea24fdb1fa/08d94/compilation-failure-variable-redeclaration-expanding-unwrap.webp 2144w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), `\n  `, React.createElement(MDXTag, {\n      name: \"img\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/4f67b11a38fb483fa19b34ea24fdb1fa/08d94/compilation-failure-variable-redeclaration-expanding-unwrap.webp\",\n        \"alt\": \"A Compilation Failure Caused by Variable Redeclaration Brought By Expanding The #unwrap Macro\",\n        \"title\": \"A compilation failure caused by variable redeclaration brought by expanding the #unwrap macro.\",\n        \"width\": 712,\n        \"height\": 477,\n        \"loading\": \"lazy\"\n      }\n    }))), `\n    `, React.createElement(MDXTag, {\n      name: \"figcaption\",\n      components: components,\n      parentName: \"figure\"\n    }, `\n        `, React.createElement(MDXTag, {\n      name: \"span\",\n      components: components,\n      parentName: \"figcaption\"\n    }, `\n            A compilation failure caused by variable redeclaration brought by expanding the #unwrap macro.\n        `), `\n    `))), React.createElement(MDXTag, {\n      name: \"h3\",\n      components: components\n    }, `Name Conflicts in Attached Macros`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Potential name conflicts can arise not only from freestanding macros but\nalso from attached macros. We can learn this from the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@COW`), ` macro example\nin the previous post. Let's recall the macro expansion of this example:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@COW\nstruct User {\n\n  // @COW expansion began\n  private class Storage {\n\n    var name: String\n\n    // other properties ...\n\n  }\n\n  private var _$storage: Storage\n\n  private func makeStorageUniqueIfNeeded() {\n    if !isKnownUniquelyReferenced(&_$storage) {\n      _$storage = Storage(name: name, ...)\n    }\n  }\n\n  init(name: String, ...) {\n    self._storage = Storage(name: name, ...)\n  }\n  // @COW expansion ended\n\n  // @COW expansion began\n  @COWIncluded(storage: _$storage)\n  // @COW expansion ended\n  var name: String {\n    // @COWIncluded expansion began\n    get { return _$storage.name }\n    set {\n      makeStorageUniqueIfNeeded()\n      _$storage.name = newValue\n    }\n    // @COWIncluded expansion ended\n  }\n\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `You may have noticed that there is a member added in the expansion that is\nnamed with a pattern that has a `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `_$`), ` prefix.`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `  private var _$storage: Storage\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `This is a naming convention that I picked from Apple's implementation of\nthe macros in Swift Observation and SwiftData which keeps the\nimplementation details of an attached macro from the programmer's\nunintentional access. However, this does not protect those members from\nunintentional redeclaration or access brought by other macros -- there\ncould be other macros that are applied by the programmer that add members\nwith duplicate names or misuse members added by other macros.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `For example, let's say there was a macro called `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@DictionaryLike`), ` which\nmakes the applied type behave like a dictionary by adding a pair of\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `subscript`), ` getter and setter. Then we apply `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@DictionaryLike`), ` on the\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `User`), ` struct we used in the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@COW`), ` macro example:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@DictionaryLike\nstruct User {\n\n  // Other contents ...\n\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `The `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@DictionaryLike`), ` could be expanded as the following code:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@DictionaryLike\nstruct User {\n\n  // Other contents ...\n\n  // @DictionaryLike exapnsion began\n  var _$storage: [String : Any] = [:]\n\n  subscript(_ key: String) -> Any? {\n    get { return _$storage[key] }\n    set { _$storage[key] = newValue }\n  }\n  // @DictionaryLike exapnsion ended\n\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Once we stack up `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@COW`), ` and `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@DictionaryLike`), ` together on the same type,\nthen there come to the situation that both `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@COW`), ` and `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@DictionaryLike`), `\nadds a member named `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `_$storage`), ` to the applied type.`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@COW\n@DictionaryLike\nstruct User {\n\n  // Other contents ...\n\n  // Brought by @COW's expansion\n  var _$storage: Storage\n\n  // Brought by @DictionaryLike's expansion\n  var _$storage: [String : Any] = [:]\n\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `This obviously would not get compiled in Swift because Swift does not\nallow overloads on properties. In this case, we would get the “invalid\nredeclaration of a variable” error again.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"figure\",\n      components: components,\n      parentName: \"p\"\n    }, `\n    `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"figure\",\n      props: {\n        \"href\": \"/static/4d9bf7fd02b4bcede954432a5c24571c/08d94/compilation-failure-variable-redeclaration-expanding-dictionary-like.webp\"\n      }\n    }, React.createElement(MDXTag, {\n      name: \"picture\",\n      components: components,\n      parentName: \"a\"\n    }, `\n  `, React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/4d9bf7fd02b4bcede954432a5c24571c/0cc25/compilation-failure-variable-redeclaration-expanding-dictionary-like.png\",\n        \"srcSet\": [\"/static/4d9bf7fd02b4bcede954432a5c24571c/5116e/compilation-failure-variable-redeclaration-expanding-dictionary-like.png 178w\", \"/static/4d9bf7fd02b4bcede954432a5c24571c/92f55/compilation-failure-variable-redeclaration-expanding-dictionary-like.png 356w\", \"/static/4d9bf7fd02b4bcede954432a5c24571c/0cc25/compilation-failure-variable-redeclaration-expanding-dictionary-like.png 712w\", \"/static/4d9bf7fd02b4bcede954432a5c24571c/7ae06/compilation-failure-variable-redeclaration-expanding-dictionary-like.png 1068w\", \"/static/4d9bf7fd02b4bcede954432a5c24571c/eee47/compilation-failure-variable-redeclaration-expanding-dictionary-like.png 1424w\", \"/static/4d9bf7fd02b4bcede954432a5c24571c/38407/compilation-failure-variable-redeclaration-expanding-dictionary-like.png 2136w\", \"/static/4d9bf7fd02b4bcede954432a5c24571c/240a0/compilation-failure-variable-redeclaration-expanding-dictionary-like.png 2144w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/4d9bf7fd02b4bcede954432a5c24571c/690c8/compilation-failure-variable-redeclaration-expanding-dictionary-like.webp\",\n        \"srcSet\": [\"/static/4d9bf7fd02b4bcede954432a5c24571c/25c8a/compilation-failure-variable-redeclaration-expanding-dictionary-like.webp 178w\", \"/static/4d9bf7fd02b4bcede954432a5c24571c/60698/compilation-failure-variable-redeclaration-expanding-dictionary-like.webp 356w\", \"/static/4d9bf7fd02b4bcede954432a5c24571c/690c8/compilation-failure-variable-redeclaration-expanding-dictionary-like.webp 712w\", \"/static/4d9bf7fd02b4bcede954432a5c24571c/d7e52/compilation-failure-variable-redeclaration-expanding-dictionary-like.webp 1068w\", \"/static/4d9bf7fd02b4bcede954432a5c24571c/456ef/compilation-failure-variable-redeclaration-expanding-dictionary-like.webp 1424w\", \"/static/4d9bf7fd02b4bcede954432a5c24571c/2a654/compilation-failure-variable-redeclaration-expanding-dictionary-like.webp 2136w\", \"/static/4d9bf7fd02b4bcede954432a5c24571c/08d94/compilation-failure-variable-redeclaration-expanding-dictionary-like.webp 2144w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), `\n  `, React.createElement(MDXTag, {\n      name: \"img\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/4d9bf7fd02b4bcede954432a5c24571c/08d94/compilation-failure-variable-redeclaration-expanding-dictionary-like.webp\",\n        \"alt\": \"A Compilation Failure Caused by Variable Redeclaration Brought By Expanding The @DictionaryLike Macro\",\n        \"title\": \"A compilation failure caused by variable redeclaration brought by expanding the @DictionaryLike macro.\",\n        \"width\": 712,\n        \"height\": 477,\n        \"loading\": \"lazy\"\n      }\n    }))), `\n    `, React.createElement(MDXTag, {\n      name: \"figcaption\",\n      components: components,\n      parentName: \"figure\"\n    }, `\n        `, React.createElement(MDXTag, {\n      name: \"span\",\n      components: components,\n      parentName: \"figcaption\"\n    }, `\n            A compilation failure caused by variable redeclaration brought by expanding the @DictionaryLike macro.\n        `), `\n    `))), React.createElement(MDXTag, {\n      name: \"h3\",\n      components: components\n    }, `Name Conflicts for Unique Language Structures`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Some language structures in Swift are unique under the superstructure.\nThis means when multiple macros try to generate the same substructure in\nthe same superstructure, the code becomes uncompilable. For example, the\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `get`), ` and `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `set`), ` accessor in a property declaration -- if we add multiple\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `get`), ` accessors in a property declaration, then the code does not compile.\nThis mistake merely happens in hand-rolled code but could be a concern\nwhen we are using macros.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `We can delve into this by starting from the previous `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@DictionaryLike`), `\nexample. Let's consider there is an attached accessor macro called\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@UseDictionaryStorage`), ` which generates `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `get`), ` and `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `set`), ` accessor for the\nattached property. The getter and setter forward access to the storage\nwhich is brought by the expansion of `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@DictionaryLike`), `.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Before macro expansion:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@COW\n@DictionaryLike\nstruct User {\n  \n  @UseDictionaryStorage\n  var info: [String : Any]?\n\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `After macro expansion:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@COW\n@DictionaryLike\nstruct User {\n  \n  @UseDictionaryStorage\n  var info: [String : Any]? {\n    // @UseDictionaryStorage exapnsion began\n    get {\n      return _$storage[\"info\"] as? [String : Any]?\n    }\n    set {\n      _$storage[\"info\"] = newValue\n    }\n    // @UseDictionaryStorage exapnsion ended\n  }\n\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `However, that's oversimplified what happened. The real expansion result\nwith `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@COW`), ` macro is:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@COW\n@DictionaryLike\nstruct User {\n  \n  @UseDictionaryStorage\n  @COWIncluded\n  var info: [String : Any]? {\n    // @COWIncluded expansion began\n    get {\n      _$storage.info\n    }\n    set {\n      makeStorageUniqueIfNeeded()\n      _$storage.info = newValue\n    }\n    // @COWIncluded expansion ended\n    // @UseDictionaryStorage exapnsion began\n    get {\n      return _$storage[\"info\"] as? [String : Any]?\n    }\n    set {\n      _$storage[\"info\"] = newValue\n    }\n    // @UseDictionaryStorage exapnsion ended\n  }\n\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `We can observe that two `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `get`), ` and `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `set`), ` accessors are generated under the\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `info`), ` property. Since the grammar of the Swift programming language only\nallows one `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `get`), `/`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `set`), ` accessor in one property, this expansion would lead\nto incorrect syntax in Swift and ultimately make the code not compile.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `However, this is actual seeing through a narrow lens. By applying the\nproduction level implementation of the COW macro, we can find that the\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `get`), ` and `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `set`), ` accessors are optimized into `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `_read`), ` and `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `_modify`), ` which\ncould offer better performance in production environment. At the same\ntime, we also can observe that the Swift programming language forbids the\nprogrammer to define multiple accessors that not only with the same name\nbut actually the same semantics.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"figure\",\n      components: components,\n      parentName: \"p\"\n    }, `\n    `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"figure\",\n      props: {\n        \"href\": \"/static/686809cc655d105e165ef129686d4370/08d94/compilation-failure-duplicate-accessor-expanding-use-dictionary-storage.webp\"\n      }\n    }, React.createElement(MDXTag, {\n      name: \"picture\",\n      components: components,\n      parentName: \"a\"\n    }, `\n  `, React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/686809cc655d105e165ef129686d4370/0cc25/compilation-failure-duplicate-accessor-expanding-use-dictionary-storage.png\",\n        \"srcSet\": [\"/static/686809cc655d105e165ef129686d4370/5116e/compilation-failure-duplicate-accessor-expanding-use-dictionary-storage.png 178w\", \"/static/686809cc655d105e165ef129686d4370/92f55/compilation-failure-duplicate-accessor-expanding-use-dictionary-storage.png 356w\", \"/static/686809cc655d105e165ef129686d4370/0cc25/compilation-failure-duplicate-accessor-expanding-use-dictionary-storage.png 712w\", \"/static/686809cc655d105e165ef129686d4370/7ae06/compilation-failure-duplicate-accessor-expanding-use-dictionary-storage.png 1068w\", \"/static/686809cc655d105e165ef129686d4370/eee47/compilation-failure-duplicate-accessor-expanding-use-dictionary-storage.png 1424w\", \"/static/686809cc655d105e165ef129686d4370/38407/compilation-failure-duplicate-accessor-expanding-use-dictionary-storage.png 2136w\", \"/static/686809cc655d105e165ef129686d4370/240a0/compilation-failure-duplicate-accessor-expanding-use-dictionary-storage.png 2144w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/686809cc655d105e165ef129686d4370/690c8/compilation-failure-duplicate-accessor-expanding-use-dictionary-storage.webp\",\n        \"srcSet\": [\"/static/686809cc655d105e165ef129686d4370/25c8a/compilation-failure-duplicate-accessor-expanding-use-dictionary-storage.webp 178w\", \"/static/686809cc655d105e165ef129686d4370/60698/compilation-failure-duplicate-accessor-expanding-use-dictionary-storage.webp 356w\", \"/static/686809cc655d105e165ef129686d4370/690c8/compilation-failure-duplicate-accessor-expanding-use-dictionary-storage.webp 712w\", \"/static/686809cc655d105e165ef129686d4370/d7e52/compilation-failure-duplicate-accessor-expanding-use-dictionary-storage.webp 1068w\", \"/static/686809cc655d105e165ef129686d4370/456ef/compilation-failure-duplicate-accessor-expanding-use-dictionary-storage.webp 1424w\", \"/static/686809cc655d105e165ef129686d4370/2a654/compilation-failure-duplicate-accessor-expanding-use-dictionary-storage.webp 2136w\", \"/static/686809cc655d105e165ef129686d4370/08d94/compilation-failure-duplicate-accessor-expanding-use-dictionary-storage.webp 2144w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), `\n  `, React.createElement(MDXTag, {\n      name: \"img\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/686809cc655d105e165ef129686d4370/08d94/compilation-failure-duplicate-accessor-expanding-use-dictionary-storage.webp\",\n        \"alt\": \"A Compilation Failure Caused by Duplicate Accessor Brought By Expanding The @UseDictionaryStorage Macro\",\n        \"title\": \"A compilation failure caused by duplicate accessor brought by expanding the @UseDictionaryStorage macro.\",\n        \"width\": 712,\n        \"height\": 561,\n        \"loading\": \"lazy\"\n      }\n    }))), `\n    `, React.createElement(MDXTag, {\n      name: \"figcaption\",\n      components: components,\n      parentName: \"figure\"\n    }, `\n        `, React.createElement(MDXTag, {\n      name: \"span\",\n      components: components,\n      parentName: \"figcaption\"\n    }, `\n            A compilation failure caused by duplicate accessor brought by expanding the @UseDictionaryStorage macro.\n        `), `\n    `))), React.createElement(MDXTag, {\n      name: \"h3\",\n      components: components\n    }, `Name Conflicts by Referring Declarations in Other Frameworks`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Since we've learned several cases of potential name conflicts caused by\nadding declarations, you might think that the list of name conflicts has\nended.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `But no. Name conflicts not only can arise from declarations like variables\nand property accessors but also references to declarations in other\nframeworks. I would like to show you how we could be cornered into this\nsituation by refactoring the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@COW`), ` macro example.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `The `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@COW`), ` macro example I've shown above is a naïve implementation -- the\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `makeStorageUniqueIfNeeded`), ` function is redundant and can be eliminated by\nbeing extracted into a type called `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Box`), ` that is bundled with the library\ncontaining the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@COW`), ` macro. To streamline the use of this type in macro\nexpansions, we could also make it a property wrapper. Here is the example\ncode:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@propertyWrapper\npublic struct Box<Contents> {\n  \n  private class Heap {\n    \n    var contents: Contents\n    \n    init(contents: Contents) { self.contents = contents }\n    \n  }\n  \n  private var heap: Heap\n  \n  public init(wrappedValue: Contents) {\n    heap = Heap(contents: wrappedValue)\n  }\n  \n  public var wrappedValue: Contents {\n    get { heap.contents }\n    set {\n      makeUniqueHeapIfNeeded()\n      heap.contents = newValue\n    }\n  }\n  \n  private mutating func makeUniqueHeapIfNeeded() {\n    guard !isKnownUniquelyReferenced(&heap) else { return }\n    heap = Heap(contents: heap.contents)\n  }\n  \n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Then we can attach `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@Box`), ` in the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `_$storage`), ` property brought by the macro\nexpansion such that we can eliminate generating the\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `makeStorageUniqueIfNeeded`), ` function in place. This reduces the redundancy\nand increases the speed of compilation. The macro's implementation is more\nsophisticated now.`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@COW\nstruct User {\n\n  // @COW expansion began\n  private struct Storage {\n\n    var name: String\n\n    // other properties ...\n\n  }\n\n  @Box\n  private var _$storage: Storage\n\n  init(name: String, ...) {\n    self._$storage = Storage(name: name, ...)\n  }\n  // @COW expansion ended\n\n  // @COW expansion began\n  @COWIncluded(storage: _$storage)\n  // @COW expansion ended\n  var name: String {\n    // @COWIncluded expansion began\n    get { return _$storage.name }\n    set { _$storage.name = newValue }\n    // @COWIncluded expansion ended\n  }\n\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `However, the type name `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Box`), ` may be ambiguous -- there could be other\nframeworks that also have a type called `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Box`), `. This ambiguity could also\nmake the code uncompilable. The following snapshot shows how the\nproduction level implementation of the COW macro resolves this issue:`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"figure\",\n      components: components,\n      parentName: \"p\"\n    }, `\n    `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"figure\",\n      props: {\n        \"href\": \"/static/d5527b4791abb33a86e4a8185a3e99a9/08d94/prod-level-cow-macro-resolves-non-fully-qualified-name-conflicts.webp\"\n      }\n    }, React.createElement(MDXTag, {\n      name: \"picture\",\n      components: components,\n      parentName: \"a\"\n    }, `\n  `, React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/d5527b4791abb33a86e4a8185a3e99a9/0cc25/prod-level-cow-macro-resolves-non-fully-qualified-name-conflicts.png\",\n        \"srcSet\": [\"/static/d5527b4791abb33a86e4a8185a3e99a9/5116e/prod-level-cow-macro-resolves-non-fully-qualified-name-conflicts.png 178w\", \"/static/d5527b4791abb33a86e4a8185a3e99a9/92f55/prod-level-cow-macro-resolves-non-fully-qualified-name-conflicts.png 356w\", \"/static/d5527b4791abb33a86e4a8185a3e99a9/0cc25/prod-level-cow-macro-resolves-non-fully-qualified-name-conflicts.png 712w\", \"/static/d5527b4791abb33a86e4a8185a3e99a9/7ae06/prod-level-cow-macro-resolves-non-fully-qualified-name-conflicts.png 1068w\", \"/static/d5527b4791abb33a86e4a8185a3e99a9/eee47/prod-level-cow-macro-resolves-non-fully-qualified-name-conflicts.png 1424w\", \"/static/d5527b4791abb33a86e4a8185a3e99a9/38407/prod-level-cow-macro-resolves-non-fully-qualified-name-conflicts.png 2136w\", \"/static/d5527b4791abb33a86e4a8185a3e99a9/240a0/prod-level-cow-macro-resolves-non-fully-qualified-name-conflicts.png 2144w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/d5527b4791abb33a86e4a8185a3e99a9/690c8/prod-level-cow-macro-resolves-non-fully-qualified-name-conflicts.webp\",\n        \"srcSet\": [\"/static/d5527b4791abb33a86e4a8185a3e99a9/25c8a/prod-level-cow-macro-resolves-non-fully-qualified-name-conflicts.webp 178w\", \"/static/d5527b4791abb33a86e4a8185a3e99a9/60698/prod-level-cow-macro-resolves-non-fully-qualified-name-conflicts.webp 356w\", \"/static/d5527b4791abb33a86e4a8185a3e99a9/690c8/prod-level-cow-macro-resolves-non-fully-qualified-name-conflicts.webp 712w\", \"/static/d5527b4791abb33a86e4a8185a3e99a9/d7e52/prod-level-cow-macro-resolves-non-fully-qualified-name-conflicts.webp 1068w\", \"/static/d5527b4791abb33a86e4a8185a3e99a9/456ef/prod-level-cow-macro-resolves-non-fully-qualified-name-conflicts.webp 1424w\", \"/static/d5527b4791abb33a86e4a8185a3e99a9/2a654/prod-level-cow-macro-resolves-non-fully-qualified-name-conflicts.webp 2136w\", \"/static/d5527b4791abb33a86e4a8185a3e99a9/08d94/prod-level-cow-macro-resolves-non-fully-qualified-name-conflicts.webp 2144w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), `\n  `, React.createElement(MDXTag, {\n      name: \"img\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/d5527b4791abb33a86e4a8185a3e99a9/08d94/prod-level-cow-macro-resolves-non-fully-qualified-name-conflicts.webp\",\n        \"alt\": \"The Production Level of @COW Macro Resolves Potential Name Conflicts\",\n        \"title\": \"The production level of @COW macro resolves potential name conflicts.\",\n        \"width\": 712,\n        \"height\": 497,\n        \"loading\": \"lazy\"\n      }\n    }))), `\n    `, React.createElement(MDXTag, {\n      name: \"figcaption\",\n      components: components,\n      parentName: \"figure\"\n    }, `\n        `, React.createElement(MDXTag, {\n      name: \"span\",\n      components: components,\n      parentName: \"figcaption\"\n    }, `\n            The production level of @COW macro resolves potential name conflicts.\n        `), `\n    `))), React.createElement(MDXTag, {\n      name: \"h3\",\n      components: components\n    }, `Semantics Conflicts`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `In the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@DictionaryLike`), ` macro example which competes `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `get`), ` and `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `set`), `\naccessors with `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@COW`), ` macro, we've learned that accessor macros may\naffect each other. However, this is not the only potential pitfall brought\nby accessor macros: some language features could also be interfered with\nby accessor macros. Look at the following example: a property wrapper\nmakes the code not compiled by being attached to a stored property in a\nstruct applied `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@COW`), ` macro.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Before the expansion:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@propertyWrapper\nstruct Capitalized {\n  \n  var wrappedValue: String {\n    didSet {\n      wrappedValue = wrappedValue.capitalized\n    }\n  }\n  \n}\n\n@COW\nstruct User {\n  \n  @Capitalized\n  var name: String = \"\"\n  \n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `After the expansion:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@COW\nstruct User {\n  \n  @COWIncluded\n  @Capitalized\n  var name: String = \"\" {\n    get {\n      return _$storage.name\n    }\n    set {\n      makeStorageUniqueIfNeeded()\n      _$storage.name = newValue\n    }\n  }\n\n  // ...\n\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `We got this expansion result because the property wrapper \"expansion\"\nhappens later than the macro expansion. With this result, the\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@Capitalized`), ` property wrapper is still attached to the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `name`), ` variable\nbut the variable is changed from a stored property into a computed\nproperty due to the macro expansion. Eventually, we would get an error\ndiagnosed by the compiler:`), React.createElement(MDXTag, {\n      name: \"blockquote\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"blockquote\"\n    }, `Property wrapper cannot be applied to a computed property`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"figure\",\n      components: components,\n      parentName: \"p\"\n    }, `\n    `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"figure\",\n      props: {\n        \"href\": \"/static/173a6a12fa03aef8eef9edefb759640c/08d94/compilation-failure-property-wrapper-applied-to-computed-property.webp\"\n      }\n    }, React.createElement(MDXTag, {\n      name: \"picture\",\n      components: components,\n      parentName: \"a\"\n    }, `\n  `, React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/173a6a12fa03aef8eef9edefb759640c/0cc25/compilation-failure-property-wrapper-applied-to-computed-property.png\",\n        \"srcSet\": [\"/static/173a6a12fa03aef8eef9edefb759640c/5116e/compilation-failure-property-wrapper-applied-to-computed-property.png 178w\", \"/static/173a6a12fa03aef8eef9edefb759640c/92f55/compilation-failure-property-wrapper-applied-to-computed-property.png 356w\", \"/static/173a6a12fa03aef8eef9edefb759640c/0cc25/compilation-failure-property-wrapper-applied-to-computed-property.png 712w\", \"/static/173a6a12fa03aef8eef9edefb759640c/7ae06/compilation-failure-property-wrapper-applied-to-computed-property.png 1068w\", \"/static/173a6a12fa03aef8eef9edefb759640c/eee47/compilation-failure-property-wrapper-applied-to-computed-property.png 1424w\", \"/static/173a6a12fa03aef8eef9edefb759640c/38407/compilation-failure-property-wrapper-applied-to-computed-property.png 2136w\", \"/static/173a6a12fa03aef8eef9edefb759640c/240a0/compilation-failure-property-wrapper-applied-to-computed-property.png 2144w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/173a6a12fa03aef8eef9edefb759640c/690c8/compilation-failure-property-wrapper-applied-to-computed-property.webp\",\n        \"srcSet\": [\"/static/173a6a12fa03aef8eef9edefb759640c/25c8a/compilation-failure-property-wrapper-applied-to-computed-property.webp 178w\", \"/static/173a6a12fa03aef8eef9edefb759640c/60698/compilation-failure-property-wrapper-applied-to-computed-property.webp 356w\", \"/static/173a6a12fa03aef8eef9edefb759640c/690c8/compilation-failure-property-wrapper-applied-to-computed-property.webp 712w\", \"/static/173a6a12fa03aef8eef9edefb759640c/d7e52/compilation-failure-property-wrapper-applied-to-computed-property.webp 1068w\", \"/static/173a6a12fa03aef8eef9edefb759640c/456ef/compilation-failure-property-wrapper-applied-to-computed-property.webp 1424w\", \"/static/173a6a12fa03aef8eef9edefb759640c/2a654/compilation-failure-property-wrapper-applied-to-computed-property.webp 2136w\", \"/static/173a6a12fa03aef8eef9edefb759640c/08d94/compilation-failure-property-wrapper-applied-to-computed-property.webp 2144w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), `\n  `, React.createElement(MDXTag, {\n      name: \"img\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/173a6a12fa03aef8eef9edefb759640c/08d94/compilation-failure-property-wrapper-applied-to-computed-property.webp\",\n        \"alt\": \"Property Wrapper Cannot Be Applied To A Computed Property\",\n        \"title\": \"Property wrapper cannot be applied to a computed property.\",\n        \"width\": 712,\n        \"height\": 397,\n        \"loading\": \"lazy\"\n      }\n    }))), `\n    `, React.createElement(MDXTag, {\n      name: \"figcaption\",\n      components: components,\n      parentName: \"figure\"\n    }, `\n        `, React.createElement(MDXTag, {\n      name: \"span\",\n      components: components,\n      parentName: \"figcaption\"\n    }, `\n            Property wrapper cannot be applied to a computed property.\n        `), `\n    `))), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `This does not only happen along with property wrappers, the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `lazy`), ` keyword\ncould also lead to the same dead end.`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@COW\nclass User {\n  \n  lazy var name: String = { \"Jane Doe\" }()\n  \n}\n`)), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@COW\nclass User {\n  \n  @COWIncluded\n  lazy var name: String = { \"Jane Doe\" }() {\n    get {\n      return _$storage.name\n    }\n    set {\n      makeStorageUniqueIfNeeded()\n      _$storage.name = newValue\n    }\n  }\n\n  // ...\n\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"figure\",\n      components: components,\n      parentName: \"p\"\n    }, `\n    `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"figure\",\n      props: {\n        \"href\": \"/static/a8215793ed0c3d4bee40a43cac146b85/08d94/compilation-failure-lazy-applied-to-computed-property.webp\"\n      }\n    }, React.createElement(MDXTag, {\n      name: \"picture\",\n      components: components,\n      parentName: \"a\"\n    }, `\n  `, React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/a8215793ed0c3d4bee40a43cac146b85/0cc25/compilation-failure-lazy-applied-to-computed-property.png\",\n        \"srcSet\": [\"/static/a8215793ed0c3d4bee40a43cac146b85/5116e/compilation-failure-lazy-applied-to-computed-property.png 178w\", \"/static/a8215793ed0c3d4bee40a43cac146b85/92f55/compilation-failure-lazy-applied-to-computed-property.png 356w\", \"/static/a8215793ed0c3d4bee40a43cac146b85/0cc25/compilation-failure-lazy-applied-to-computed-property.png 712w\", \"/static/a8215793ed0c3d4bee40a43cac146b85/7ae06/compilation-failure-lazy-applied-to-computed-property.png 1068w\", \"/static/a8215793ed0c3d4bee40a43cac146b85/eee47/compilation-failure-lazy-applied-to-computed-property.png 1424w\", \"/static/a8215793ed0c3d4bee40a43cac146b85/38407/compilation-failure-lazy-applied-to-computed-property.png 2136w\", \"/static/a8215793ed0c3d4bee40a43cac146b85/240a0/compilation-failure-lazy-applied-to-computed-property.png 2144w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/a8215793ed0c3d4bee40a43cac146b85/690c8/compilation-failure-lazy-applied-to-computed-property.webp\",\n        \"srcSet\": [\"/static/a8215793ed0c3d4bee40a43cac146b85/25c8a/compilation-failure-lazy-applied-to-computed-property.webp 178w\", \"/static/a8215793ed0c3d4bee40a43cac146b85/60698/compilation-failure-lazy-applied-to-computed-property.webp 356w\", \"/static/a8215793ed0c3d4bee40a43cac146b85/690c8/compilation-failure-lazy-applied-to-computed-property.webp 712w\", \"/static/a8215793ed0c3d4bee40a43cac146b85/d7e52/compilation-failure-lazy-applied-to-computed-property.webp 1068w\", \"/static/a8215793ed0c3d4bee40a43cac146b85/456ef/compilation-failure-lazy-applied-to-computed-property.webp 1424w\", \"/static/a8215793ed0c3d4bee40a43cac146b85/2a654/compilation-failure-lazy-applied-to-computed-property.webp 2136w\", \"/static/a8215793ed0c3d4bee40a43cac146b85/08d94/compilation-failure-lazy-applied-to-computed-property.webp 2144w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), `\n  `, React.createElement(MDXTag, {\n      name: \"img\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/a8215793ed0c3d4bee40a43cac146b85/08d94/compilation-failure-lazy-applied-to-computed-property.webp\",\n        \"alt\": \"Lazy Cannot Be Applied To A Computed Property\",\n        \"title\": \"Lazy cannot be applied to a computed property.\",\n        \"width\": 712,\n        \"height\": 313,\n        \"loading\": \"lazy\"\n      }\n    }))), `\n    `, React.createElement(MDXTag, {\n      name: \"figcaption\",\n      components: components,\n      parentName: \"figure\"\n    }, `\n        `, React.createElement(MDXTag, {\n      name: \"span\",\n      components: components,\n      parentName: \"figcaption\"\n    }, `\n            Lazy cannot be applied to a computed property.\n        `), `\n    `))), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `With these examples, we can learn that the expansion of a Swift macro\ncould change the semantics of the source code. This could lead to a\nsemantics conflict and ultimately make the expansion result not compile.`), React.createElement(MDXTag, {\n      name: \"h2\",\n      components: components\n    }, `Solutions: Progressive Control in Macro Expansion`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Till now, we've had a list of typical traps and pitfalls that one could\nstep into while implementing Swift macros. At a glance, this list might\nseem overwhelming to you. However, I invented a simple way to get rid of\nthem: progressive control in macro expansion -- which was derived from the\nidea behind \"progressive disclosure in API design\" and \"gradual typing\"\nand borrowed some ideas extracted from the implementation of Apple's Swift\nObservation and SwiftData.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `The idea behind \"progressive control in macro expansion\" is quite simple:\nif there are no conflicts, then the programmer shall not make any effort\nto workaround the conflict-resolving mechanisms. Or, there must be tools\nthat allow the programmer to resolve the conflicts with minimal effort.`), React.createElement(MDXTag, {\n      name: \"h3\",\n      components: components\n    }, `Maximize the Probability of the Lucky Case`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `If a programmer does not have to resolve any conflicts while applying\nSwift macros, then we can say the programmer gets a lucky case. To\nmaximize the likelihood that a Swift macro user gets a favorable outcome,\nwe must adhere to the following items:`), React.createElement(MDXTag, {\n      name: \"blockquote\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"blockquote\"\n    }, `Item 1: Macros that manipulate control flow should have names that\nreflect this purpose.`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `This item is for getting avoid misuse of the previously mentioned\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `#unwrap`), ` macro:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `func foo(_ bar: Int?) {\n  for _ in 0..<10 {\n    #unwrap(bar) {\n      print(bar)\n    }\n  }\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `which is expanded into:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `func foo(_ bar: Int?) {\n  for _ in 0..<10 {\n    // #unwrap expansion began\n    guard let bar = bar else {\n      return\n    }\n    print(bar)\n    // #unwrap expansion ended\n  }\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `The programmers could find it much easier to get rid of such a pitfall by\nrenaming this macro into `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `#returnIfAnyOptional`), `.`), React.createElement(MDXTag, {\n      name: \"blockquote\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"blockquote\"\n    }, `Item 2: Put the macro expansion under an \"umbrella\" if this matches your\ndesign.`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `This would make your macro expansion get rid of most member redeclaration\nerrors. For example, to avoid resolving the name conflict that is caused\nby turning variable shadowing into variable redeclaration in the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `#unwrap`), `\nmacro, we can use a `, React.createElement(MDXTag, {\n      name: \"strong\",\n      components: components,\n      parentName: \"p\"\n    }, `closure`), ` as the \"umbrella\" to protect the macro\nexpansion:`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Problematic expansion:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `func foo(_ bar: Int?) {\n  // \\`updater\\` defined the first time\n  let updater = Updater()\n  // #unwrap expansion began\n  guard let bar else {\n    return\n  }\n  // \\`updater\\` defined the second time\n  let updater = Updater()\n  print(bar)\n  updater.update()\n  // #unwrap expansion ended\n  print(updater.description)\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Fixed expansion with closure:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `func foo(_ bar: Int?) {\n  // \\`updater\\` defined the first time\n  let updater = Updater()\n  // #unwrap expansion began\n  guard let bar else {\n    return\n  }\n  { (bar) in\n    // \\`updater\\` defined the second time\n    let updater = Updater()\n    print(bar)\n    updater.update()\n  }(bar)\n  // #unwrap expansion ended\n  print(updater.description)\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `However, once the body of the closure involves control flows, the closure\nwould not get inlined by the optimizer in its performance inlining pass.\nThis could leave the body of the closure out of the local analysis and the\noptimization of the macro's apply site. In some cases, this also means to\nlarger code size. To get rid of this situation, we could use the local\nfunction instead of closure and attribute the local function as\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@inline(__always)`), ` to build the \"umbrella\".`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Fixed expansion with local function:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `func foo(_ bar: Int?) {\n  // \\`updater\\` defined the first time\n  let updater = Updater()\n  // #unwrap expansion began\n  guard let bar else {\n    return true\n  }\n  @inline(__always)\n  func unwrapped(bar: Int) -> Void {\n    // \\`updater\\` defined the second time\n    let updater = Updater()\n    print(bar)\n    updater.update()\n  }\n  unwrapped(bar)\n  // #unwrap expansion ended\n  print(updater.description)\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `This \"umbrella\"-like structure could also be in expansions of attached\nmacros -- the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@COW`), ` macro's expansion declares a nested `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Storage`), ` type as\nthe storage. This nested type would work like the aforementioned\n\"umbrella\" -- it would protect its member from redeclaration with a type\nscope.`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@COW\nstruct User {\n\n  // @COW expansion began\n  private struct Storage {\n\n    var name: String\n\n    // other properties ...\n\n  }\n\n  // Unnecessary expansions ...\n\n  // @COW expansion ended\n  \n  // Unnecessary contents ...\n\n}\n`)), React.createElement(MDXTag, {\n      name: \"blockquote\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"blockquote\"\n    }, `Item 3: Referring types, functions or variables from frameworks other\nthan the standard library with fully-qualified names.`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `In the example of introducing the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@Box`), ` property wrapper to the expansion\nof the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@COW`), ` macro, we can find the name `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Box`), ` itself could be ambiguous\nsince other imported frameworks may have a declaration in the same name.\nWe can fix this by using a fully-qualified name. Let's say the name of the\nlibrary is just `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `COW`), ` then the fully-qualified name of `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Box`), ` is `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `COW.Box`), `.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `The macro expansion before the fix:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@COW\nstruct User {\n\n  // @COW expansion began\n\n  // Unnecessary expansions ...\n  \n  @Box\n  private var _$storage: Storage\n\n  // Unnecessary expansions ...\n\n  // @COW expansion ended\n\n  // Unnecessary contents ...\n\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `The macro expansion after the fix:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@COW\nstruct User {\n\n  // @COW expansion began\n\n  // Unnecessary expansions ...\n  \n  @COW.Box\n  private var _$storage: Storage\n\n  // Unnecessary expansions ...\n\n  // @COW expansion ended\n\n  // Unnecessary contents ...\n\n}\n`)), React.createElement(MDXTag, {\n      name: \"h3\",\n      components: components\n    }, `Minimize the Effort of Resolving Conflicts`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `However, we cannot ensure the programmers always get the lucky case. There\nmust be cases where programmers shall resolve the conflicts by themselves.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `By applying the aforementioned items, there are still potential name and\nsemantics conflicts that lie ahead of us. The only thing we can do is to\nface and resolve them: since we cannot assume that one single macro author\ncan predict what names all other macro authors could pick, at the same\ntime, invariant semantics definitely should not be a property of Swift\nmacro expansion because it could decrease the flexibility of the Siwft\nMacro. An ideal situation would be to have a set of conflict-resolving\ntools that lie on a smooth curve of the cost of use. And there they are:`), React.createElement(MDXTag, {\n      name: \"blockquote\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"blockquote\"\n    }, `Item 4: Use the programmer's declarations if something in your macro\nexpansion is declared by the programmer.`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `With this item, the programmer still makes zero effort to resolve the\nconflict. The mechanism described in this item is adopted by some AST\ntransforming language features like `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Equatable`), ` and `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Hashable`), ` -- the\ncompiler stops implementing these protocols on behalf of the programmers\nif the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Equatable`), ` or `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Hashable`), ` has already been implemented by the\nprogrammer. It could also be observed in Swift Observation when the\nprogrammer implemented the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `access`), ` function or `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `withMutation`), ` function.\nSince the mechanism itself is ubiquitous, the learning curve should also\nbe gentle.`), React.createElement(MDXTag, {\n      name: \"blockquote\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"blockquote\"\n    }, `Item 5: Offer a way to rename the declarations in your macro expansion\nwhen renaming the declarations is possible.`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `We could test this item in the example of stacking up the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@COW`), ` macro and\nthe `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@DictionaryLike`), ` macro on a single type, the macro expansions of the\ntwo macros generate two `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `_$storage`), ` variables. To add the renaming\nmechanism, we can naturally come up with the idea that to add an argument\nto the macro:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@attached(member, names: arbitrary)\n@attached(memberAttribute)\npublic macro COW(storageName: String) =\n  #externalMacro(module: \"COWMacros\", type: \"COWMacro\")\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `But this would break the idea behind \"progressive control in macro\nexpansion\": if there are no conflicts, then the programmer shall not care\nabout resolving the conflicts -- with this macro declaration, the\nprogrammer shall always apply this macro with an additional argument this\ntime. However, what might be something new to you is this also could be\ndone by macro overloading. This means there could be multiple macros with\nthe same name but have different \"signatures\".`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@attached(member, names: arbitrary)\n@attached(memberAttribute)\npublic macro COW() =\n  #externalMacro(module: \"COWMacros\", type: \"COWMacro\")\n\n@attached(member, names: arbitrary)\n@attached(memberAttribute)\npublic macro COW(storageName: String) =\n  #externalMacro(module: \"COWMacros\", type: \"COWMacro\")\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Firstly, let's recall the expansion before adding the renaming mechanism\nto each macro.`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@COW\n@DictionaryLike\nstruct User {\n\n  // Other contents ...\n\n  // Brought by @COW's expansion\n  var _$storage: Storage\n\n  // Brought by @DictionaryLike's expansion\n  var _$storage: [String : Any] = [:]\n\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Then, there is the expansion after adding the renaming mechanism to each\nmacro.`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@COW(storageName: \"_$cowStorage\")\n@DictionaryLike(storageName: \"_$dictStorage\")\nstruct User {\n\n  // Other contents ...\n\n  // Brought by @COW's expansion\n  var _$cowStorage: Storage\n\n  // Brought by @DictionaryLike's expansion\n  var _$dictStorage: [String : Any] = [:]\n\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `However, there could be generated declarations that couldn't be renamed,\nsuch as the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `get`), ` and `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `set`), ` accessor. Then we would come to the most\nexpensive item:`), React.createElement(MDXTag, {\n      name: \"blockquote\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"blockquote\"\n    }, `Item 6: Offer a way to stop code generation when the generated code\ninvolves unique language structures in a superstructure.`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Swift Observation offers a good example for this item and here is the\nexample: an `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@Observable`), ` macro attached class with a property attached\nwith the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@Capitalized`), ` property wrapper:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@propertyWrapper\nstruct Capitalized {\n  \n  var wrappedValue: String {\n    didSet {\n      wrappedValue = wrappedValue.capitalized\n    }\n  }\n  \n}\n\n@Observable\nclass User {\n  \n  @Capitalized\n  var name: String\n\n  init(name: String) {\n    self.name = name\n  }\n  \n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `The code above does not compile due to the property wrapper requires the\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `name`), ` to be a stored property but `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@Observable`), ` transforms it into a\ncomputed property.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"figure\",\n      components: components,\n      parentName: \"p\"\n    }, `\n    `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"figure\",\n      props: {\n        \"href\": \"/static/26417a27e9cf5bf2cfb955e35013f678/08d94/compilation-failure-observable-transforms-stored-property-into-computed.webp\"\n      }\n    }, React.createElement(MDXTag, {\n      name: \"picture\",\n      components: components,\n      parentName: \"a\"\n    }, `\n  `, React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/26417a27e9cf5bf2cfb955e35013f678/0cc25/compilation-failure-observable-transforms-stored-property-into-computed.png\",\n        \"srcSet\": [\"/static/26417a27e9cf5bf2cfb955e35013f678/5116e/compilation-failure-observable-transforms-stored-property-into-computed.png 178w\", \"/static/26417a27e9cf5bf2cfb955e35013f678/92f55/compilation-failure-observable-transforms-stored-property-into-computed.png 356w\", \"/static/26417a27e9cf5bf2cfb955e35013f678/0cc25/compilation-failure-observable-transforms-stored-property-into-computed.png 712w\", \"/static/26417a27e9cf5bf2cfb955e35013f678/7ae06/compilation-failure-observable-transforms-stored-property-into-computed.png 1068w\", \"/static/26417a27e9cf5bf2cfb955e35013f678/eee47/compilation-failure-observable-transforms-stored-property-into-computed.png 1424w\", \"/static/26417a27e9cf5bf2cfb955e35013f678/38407/compilation-failure-observable-transforms-stored-property-into-computed.png 2136w\", \"/static/26417a27e9cf5bf2cfb955e35013f678/240a0/compilation-failure-observable-transforms-stored-property-into-computed.png 2144w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/26417a27e9cf5bf2cfb955e35013f678/690c8/compilation-failure-observable-transforms-stored-property-into-computed.webp\",\n        \"srcSet\": [\"/static/26417a27e9cf5bf2cfb955e35013f678/25c8a/compilation-failure-observable-transforms-stored-property-into-computed.webp 178w\", \"/static/26417a27e9cf5bf2cfb955e35013f678/60698/compilation-failure-observable-transforms-stored-property-into-computed.webp 356w\", \"/static/26417a27e9cf5bf2cfb955e35013f678/690c8/compilation-failure-observable-transforms-stored-property-into-computed.webp 712w\", \"/static/26417a27e9cf5bf2cfb955e35013f678/d7e52/compilation-failure-observable-transforms-stored-property-into-computed.webp 1068w\", \"/static/26417a27e9cf5bf2cfb955e35013f678/456ef/compilation-failure-observable-transforms-stored-property-into-computed.webp 1424w\", \"/static/26417a27e9cf5bf2cfb955e35013f678/2a654/compilation-failure-observable-transforms-stored-property-into-computed.webp 2136w\", \"/static/26417a27e9cf5bf2cfb955e35013f678/08d94/compilation-failure-observable-transforms-stored-property-into-computed.webp 2144w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), `\n  `, React.createElement(MDXTag, {\n      name: \"img\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/26417a27e9cf5bf2cfb955e35013f678/08d94/compilation-failure-observable-transforms-stored-property-into-computed.webp\",\n        \"alt\": \"@Observable Transforms Stored Property Into Computed\",\n        \"title\": \"@Observable transforms stored property into computed.\",\n        \"width\": 712,\n        \"height\": 313,\n        \"loading\": \"lazy\"\n      }\n    }))), `\n    `, React.createElement(MDXTag, {\n      name: \"figcaption\",\n      components: components,\n      parentName: \"figure\"\n    }, `\n        `, React.createElement(MDXTag, {\n      name: \"span\",\n      components: components,\n      parentName: \"figcaption\"\n    }, `\n            @Observable transforms stored property into computed.\n        `), `\n    `))), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Here is the key part of the macro expansion:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@Observable\nclass User {\n\n  // Unrelated expansion ...\n  \n  @Capitalized\n  // @Observable expansion began\n  @ObservationTracked\n  // @Observable expansion ended\n  var name: String {\n    // @ObservationTracked expansion began\n    init(initialValue) initializes(_name) {\n      _name = initialValue\n    }\n    get {\n      access(keyPath: \\\\.name)\n      return _name\n    }\n    set {\n      withMutation(keyPath: \\\\.name) {\n        _name = newValue\n      }\n    }\n    // @ObservationTracked expansion ended\n  }\n  \n  // Unrelated contents ...\n  \n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `However, since Swift Observation also offers an attached macro called\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@ObservationIgnored`), ` to stop code generation brought by `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@Observable`), ` on\napplied members, we can make use of this macro to manually resolve the\nconflicts.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Firstly, we have to backward the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `name`), ` property with an underscore,\nattaching `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@ObservationIgnored`), ` on it.`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@Observable\nclass User {\n  \n  @Capitalized\n  @ObservationIgnored\n  var _name: String\n\n  // ...\n\n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Then, we can add a `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `name`), ` property, hand-rolling the observation\nmechanism:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-swift\"\n      }\n    }, `@Observable\nclass User {\n\n  // ...\n  \n  init(name: String) {\n    self.name = name\n  }\n\n  var name: String {\n    init(initialValue) initializes(__name) {\n      __name = Capitalized(wrappedValue: initialValue)\n    }\n    get {\n      access(keyPath: \\\\.name)\n      return _name\n    }\n    set {\n      withMutation(keyPath: \\\\.name) {\n        _name = newValue\n      }\n    }\n  }\n\n  // ...\n  \n}\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Finally, we resolved this conflict.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"figure\",\n      components: components,\n      parentName: \"p\"\n    }, `\n    `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"figure\",\n      props: {\n        \"href\": \"/static/5ad7cde220f79582ea9e3ced07db71c9/08d94/resolve-observable-transform-computed-property-into-stored.webp\"\n      }\n    }, React.createElement(MDXTag, {\n      name: \"picture\",\n      components: components,\n      parentName: \"a\"\n    }, `\n  `, React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/5ad7cde220f79582ea9e3ced07db71c9/0cc25/resolve-observable-transform-computed-property-into-stored.png\",\n        \"srcSet\": [\"/static/5ad7cde220f79582ea9e3ced07db71c9/5116e/resolve-observable-transform-computed-property-into-stored.png 178w\", \"/static/5ad7cde220f79582ea9e3ced07db71c9/92f55/resolve-observable-transform-computed-property-into-stored.png 356w\", \"/static/5ad7cde220f79582ea9e3ced07db71c9/0cc25/resolve-observable-transform-computed-property-into-stored.png 712w\", \"/static/5ad7cde220f79582ea9e3ced07db71c9/7ae06/resolve-observable-transform-computed-property-into-stored.png 1068w\", \"/static/5ad7cde220f79582ea9e3ced07db71c9/eee47/resolve-observable-transform-computed-property-into-stored.png 1424w\", \"/static/5ad7cde220f79582ea9e3ced07db71c9/38407/resolve-observable-transform-computed-property-into-stored.png 2136w\", \"/static/5ad7cde220f79582ea9e3ced07db71c9/240a0/resolve-observable-transform-computed-property-into-stored.png 2144w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/5ad7cde220f79582ea9e3ced07db71c9/690c8/resolve-observable-transform-computed-property-into-stored.webp\",\n        \"srcSet\": [\"/static/5ad7cde220f79582ea9e3ced07db71c9/25c8a/resolve-observable-transform-computed-property-into-stored.webp 178w\", \"/static/5ad7cde220f79582ea9e3ced07db71c9/60698/resolve-observable-transform-computed-property-into-stored.webp 356w\", \"/static/5ad7cde220f79582ea9e3ced07db71c9/690c8/resolve-observable-transform-computed-property-into-stored.webp 712w\", \"/static/5ad7cde220f79582ea9e3ced07db71c9/d7e52/resolve-observable-transform-computed-property-into-stored.webp 1068w\", \"/static/5ad7cde220f79582ea9e3ced07db71c9/456ef/resolve-observable-transform-computed-property-into-stored.webp 1424w\", \"/static/5ad7cde220f79582ea9e3ced07db71c9/2a654/resolve-observable-transform-computed-property-into-stored.webp 2136w\", \"/static/5ad7cde220f79582ea9e3ced07db71c9/08d94/resolve-observable-transform-computed-property-into-stored.webp 2144w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), `\n  `, React.createElement(MDXTag, {\n      name: \"img\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/5ad7cde220f79582ea9e3ced07db71c9/08d94/resolve-observable-transform-computed-property-into-stored.webp\",\n        \"alt\": \"Resolving The Conflicts Brought by @Observable Macro Transforming Stored Properties Into Computed\",\n        \"title\": \"Resolving the conflicts brought by @Observable macro transforming stored properties into computed.\",\n        \"width\": 712,\n        \"height\": 509,\n        \"loading\": \"lazy\"\n      }\n    }))), `\n    `, React.createElement(MDXTag, {\n      name: \"figcaption\",\n      components: components,\n      parentName: \"figure\"\n    }, `\n        `, React.createElement(MDXTag, {\n      name: \"span\",\n      components: components,\n      parentName: \"figcaption\"\n    }, `\n            Resolving the conflicts brought by @Observable macro transforming stored properties into computed.\n        `), `\n    `))), React.createElement(MDXTag, {\n      name: \"blockquote\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"blockquote\"\n    }, `Item 7: An example expansion should be included in the macro's\ndocumentation.`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `However, it is not enough to have item 6 alone. The programmers still\ncould be confused about how to manually \"expand\" the macro by itself. To\naddress this, the macro authors should include an example implementation\nthat shows how to manually expand the macro in its documentation. This\nprovides programmers with the guidance they need to manually resolve macro\nexpansion conflicts.`), React.createElement(MDXTag, {\n      name: \"h3\",\n      components: components\n    }, `Why I Didn't Recommend Using makeUniqueName(_:)`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `From the session at WWDC 2203, we learned that there is a way to get rid\nof name collision: use `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `MacroExpansionContext.makeUniqueName(_:)`), `.\nHowever, the name generated by this API is unreadable by humans. Here is\nan example:`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"figure\",\n      components: components,\n      parentName: \"p\"\n    }, `\n    `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"figure\",\n      props: {\n        \"href\": \"/static/e524d90a1635f63b290ca091f0b0e5b7/08d94/make-unique-name-result.webp\"\n      }\n    }, React.createElement(MDXTag, {\n      name: \"picture\",\n      components: components,\n      parentName: \"a\"\n    }, `\n  `, React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/e524d90a1635f63b290ca091f0b0e5b7/0cc25/make-unique-name-result.png\",\n        \"srcSet\": [\"/static/e524d90a1635f63b290ca091f0b0e5b7/5116e/make-unique-name-result.png 178w\", \"/static/e524d90a1635f63b290ca091f0b0e5b7/92f55/make-unique-name-result.png 356w\", \"/static/e524d90a1635f63b290ca091f0b0e5b7/0cc25/make-unique-name-result.png 712w\", \"/static/e524d90a1635f63b290ca091f0b0e5b7/7ae06/make-unique-name-result.png 1068w\", \"/static/e524d90a1635f63b290ca091f0b0e5b7/eee47/make-unique-name-result.png 1424w\", \"/static/e524d90a1635f63b290ca091f0b0e5b7/38407/make-unique-name-result.png 2136w\", \"/static/e524d90a1635f63b290ca091f0b0e5b7/240a0/make-unique-name-result.png 2144w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/e524d90a1635f63b290ca091f0b0e5b7/690c8/make-unique-name-result.webp\",\n        \"srcSet\": [\"/static/e524d90a1635f63b290ca091f0b0e5b7/25c8a/make-unique-name-result.webp 178w\", \"/static/e524d90a1635f63b290ca091f0b0e5b7/60698/make-unique-name-result.webp 356w\", \"/static/e524d90a1635f63b290ca091f0b0e5b7/690c8/make-unique-name-result.webp 712w\", \"/static/e524d90a1635f63b290ca091f0b0e5b7/d7e52/make-unique-name-result.webp 1068w\", \"/static/e524d90a1635f63b290ca091f0b0e5b7/456ef/make-unique-name-result.webp 1424w\", \"/static/e524d90a1635f63b290ca091f0b0e5b7/2a654/make-unique-name-result.webp 2136w\", \"/static/e524d90a1635f63b290ca091f0b0e5b7/08d94/make-unique-name-result.webp 2144w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), `\n  `, React.createElement(MDXTag, {\n      name: \"img\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/e524d90a1635f63b290ca091f0b0e5b7/08d94/make-unique-name-result.webp\",\n        \"alt\": \"makeUniqueName Generates Unreadable Names\",\n        \"title\": \"makeUniqueName generates unreadable names.\",\n        \"width\": 712,\n        \"height\": 313,\n        \"loading\": \"lazy\"\n      }\n    }))), `\n    `, React.createElement(MDXTag, {\n      name: \"figcaption\",\n      components: components,\n      parentName: \"figure\"\n    }, `\n        `, React.createElement(MDXTag, {\n      name: \"span\",\n      components: components,\n      parentName: \"figcaption\"\n    }, `\n            makeUniqueName generates unreadable names.\n        `), `\n    `))), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Do you know what it means? At least, I cannot make out what it means at\nfirst glance. We can only understand this by resolving it with\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `swift-demangle`), `:`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"figure\",\n      components: components,\n      parentName: \"p\"\n    }, `\n    `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"figure\",\n      props: {\n        \"href\": \"/static/972a342dc571254d3ef81051934e5b23/cd3ae/result-from-swift-demangle-for-make-unqiue-name-generated-names.webp\"\n      }\n    }, React.createElement(MDXTag, {\n      name: \"picture\",\n      components: components,\n      parentName: \"a\"\n    }, `\n  `, React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/972a342dc571254d3ef81051934e5b23/0cc25/result-from-swift-demangle-for-make-unqiue-name-generated-names.png\",\n        \"srcSet\": [\"/static/972a342dc571254d3ef81051934e5b23/5116e/result-from-swift-demangle-for-make-unqiue-name-generated-names.png 178w\", \"/static/972a342dc571254d3ef81051934e5b23/92f55/result-from-swift-demangle-for-make-unqiue-name-generated-names.png 356w\", \"/static/972a342dc571254d3ef81051934e5b23/0cc25/result-from-swift-demangle-for-make-unqiue-name-generated-names.png 712w\", \"/static/972a342dc571254d3ef81051934e5b23/7ae06/result-from-swift-demangle-for-make-unqiue-name-generated-names.png 1068w\", \"/static/972a342dc571254d3ef81051934e5b23/eee47/result-from-swift-demangle-for-make-unqiue-name-generated-names.png 1424w\", \"/static/972a342dc571254d3ef81051934e5b23/72a5c/result-from-swift-demangle-for-make-unqiue-name-generated-names.png 1524w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), React.createElement(MDXTag, {\n      name: \"source\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/972a342dc571254d3ef81051934e5b23/690c8/result-from-swift-demangle-for-make-unqiue-name-generated-names.webp\",\n        \"srcSet\": [\"/static/972a342dc571254d3ef81051934e5b23/25c8a/result-from-swift-demangle-for-make-unqiue-name-generated-names.webp 178w\", \"/static/972a342dc571254d3ef81051934e5b23/60698/result-from-swift-demangle-for-make-unqiue-name-generated-names.webp 356w\", \"/static/972a342dc571254d3ef81051934e5b23/690c8/result-from-swift-demangle-for-make-unqiue-name-generated-names.webp 712w\", \"/static/972a342dc571254d3ef81051934e5b23/d7e52/result-from-swift-demangle-for-make-unqiue-name-generated-names.webp 1068w\", \"/static/972a342dc571254d3ef81051934e5b23/456ef/result-from-swift-demangle-for-make-unqiue-name-generated-names.webp 1424w\", \"/static/972a342dc571254d3ef81051934e5b23/cd3ae/result-from-swift-demangle-for-make-unqiue-name-generated-names.webp 1524w\"],\n        \"sizes\": \"(max-width: 712px) 100vw, 712px\"\n      }\n    }), `\n  `, React.createElement(MDXTag, {\n      name: \"img\",\n      components: components,\n      parentName: \"picture\",\n      props: {\n        \"src\": \"/static/972a342dc571254d3ef81051934e5b23/cd3ae/result-from-swift-demangle-for-make-unqiue-name-generated-names.webp\",\n        \"alt\": \"Result from swift-demangle For makeUniqueName Generated Names\",\n        \"title\": \"Result from swift-demangle for makeUniqueName generated names.\",\n        \"width\": 712,\n        \"height\": 518,\n        \"loading\": \"lazy\"\n      }\n    }))), `\n    `, React.createElement(MDXTag, {\n      name: \"figcaption\",\n      components: components,\n      parentName: \"figure\"\n    }, `\n        `, React.createElement(MDXTag, {\n      name: \"span\",\n      components: components,\n      parentName: \"figcaption\"\n    }, `\n            Result from swift-demangle for makeUniqueName generated names.\n        `), `\n    `))), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Since this name could be used at debug-time, being human-readable is\ncrucial for the sake of the efficiency of understanding the code's\npurpose. This is the reason why I didn't recommend using\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `MacroExpansionContext.makeUniqueName(_:)`), `.`), React.createElement(MDXTag, {\n      name: \"h2\",\n      components: components\n    }, `Conclusions`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `In this post, we listed some typical traps and pitfalls that one could\nstep into while authoring Swift macros. On top of that, we also discussed\na methodology to resolve all of them: \"progressive control in macro\nexpansion\", which involves 2 goals and 7 items.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `The goals of this method are:`), React.createElement(MDXTag, {\n      name: \"ul\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, `If there are no conflicts, then the programmer shall not make any effort\nto work around them by using conflict-resolving mechanisms.`), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, `Or, there must be tools that allow the programmer to resolve the\nconflicts with minimal effort.`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `The items in this method include:`), React.createElement(MDXTag, {\n      name: \"ol\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ol\"\n    }, `Macros that manipulate control flow should have names that reflect this\npurpose.`), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ol\"\n    }, `Put the macro expansion under an \"umbrella\" if this matches your\ndesign.`), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ol\"\n    }, `Referring types, functions or variables from frameworks other than the\nstandard library with fully-qualified names.`), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ol\"\n    }, `Use the programmer's declaration if something in your macro expansion\nis declared by the programmer.`), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ol\"\n    }, `Offer a way to rename the declarations in your macro expansion when\nrenaming the declarations is possible.`), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ol\"\n    }, `Offer a way to stop code generation when the generated code involves\nunique language structures in a superstructure.`), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ol\"\n    }, `An example expansion should be included in the macro's documentation.`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `In addition, we also learned that the name generated by\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `MacroExpansionContext.makeUniqueName(_:)`), ` is unreadable for human beings.\nThis decreased the efficiency of understanding the purpose of code during\ndebugging.`), React.createElement(MDXTag, {\n      name: \"h2\",\n      components: components\n    }, `Resources`), React.createElement(MDXTag, {\n      name: \"ul\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, `A playground project that implements macros in this post (needs\n`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `git checkout traps-and-pitfalls`), `):`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, `  `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"p\",\n      props: {\n        \"href\": \"https://github.com/WeZZard/SwiftMacroRevisited\"\n      }\n    }, `WeZZard/SwiftMacroRevisited`))), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, `The production level implementation of the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@COW`), ` macro:`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"p\",\n      props: {\n        \"href\": \"https://github.com/wezzard/cowmacro\"\n      }\n    }, `WeZZard/COW Macro`)))));\n  }\n\n}\nMDXContent.isMDXComponent = true;","scope":""},"headings":[{"value":"Traps and Pitfalls","depth":2},{"value":"Potential Chaos in Control Flow","depth":3},{"value":"Name Conflicts in Freestanding Macros","depth":3},{"value":"Name Conflicts in Attached Macros","depth":3},{"value":"Name Conflicts for Unique Language Structures","depth":3},{"value":"Name Conflicts by Referring Declarations in Other Frameworks","depth":3},{"value":"Semantics Conflicts","depth":3},{"value":"Solutions: Progressive Control in Macro Expansion","depth":2},{"value":"Maximize the Probability of the Lucky Case","depth":3},{"value":"Minimize the Effort of Resolving Conflicts","depth":3},{"value":"Why I Didn't Recommend Using makeUniqueName(_:)","depth":3},{"value":"Conclusions","depth":2},{"value":"Resources","depth":2}]}}},"earlierPostExcerpt":{"slug":"/post/2023/08/swift-macro-revisited-the-strengths-and-essence-a5a4","title":"Swift Macro: Revisited - The Strengths and Essence","subtitle":"","createdTime":"2023-08-08T00:00:00.000Z","tags":["Swift","Macro"],"category":"Programming","file":{"childMdx":{"excerpt":"From the sessions at WWDC 2023, we learned that Swift Macro aims to: Eliminate boilerplates Make tedious things easy Share with other developers in packages However, these goals aren't unique to Swift Macro. They are common\nobjectives for many code reuse methods in Swift, such as functions, types…"}}},"laterPostExcerpt":{"slug":"/post/2025/03/when-the-swift-compiler-deleted-code-in-stdlib-9067","title":"When the Swift Compiler Deleted Code in Stdlib - A Note of Fixing the Eliminate Redundant Load Pass in Swift 6","subtitle":"","createdTime":"2025-03-09T00:00:00.000Z","tags":["Swift","Compiler"],"category":"Programming","file":{"childMdx":{"excerpt":"Latest updated: Apple has accepted the fix for this issue. The final\nsolution was adjusted following a review by the relevant code owner. Right before the Chinese New Year vacation of the Year of the Snake, a\ncolleague showed me a mysterious crash caused by a use-after-free error.\nRecently, I found…"}}}},"pageContext":{"postId":"5dad251c-7c9d-519a-89a1-db4f32ea4fcb","earlierPostId":"f2b372f7-8c6e-5cc2-9792-84dc1fac5aa9","laterPostId":"a1a051bd-7086-59a6-83e9-167b8d7512f2"}}