Avatar
3週間ほど休暇を取っていたのでまったく追えていないのですが、プロポーザルを読む限り:
  • マクロの引数がタイプチェックされるのと同様に、ボディも展開前タイプチェックするかどうかは完全にデザイン選択の問題です。 タイプチェックしたほうが嬉しい場合もあるということですね
if they are fully type-checked prior to expansion, then the bodies are easier to reason about for programmers and also for tools.
  • プロポーザルで述べられている関数ボディマクロは3種
1) 元のボディがない → 展開前タイプチェック不要 @attached(body) macro Remote func f(a: Int, b: String) async throws -> String 2) 元のボディの前に何かを挿入する → 展開前タイプチェックする @attached(preamble) macro Logged func g(a: Int, b: Int) -> Int { return a + b } 3) 元のボディを書き換える → 展開前タイプチェックしない @attached(body) macro Traced @Traced("Doing complicated math") func h(a: Int, b: Int) -> Int { return a + b }
  • 3 のパターンにおいて、展開前にタイプチェック_しない_ことでマクロで追加される変数名を使えるなどの利点がある一方、 その関数ボディ内でのコード補完や Jump to Definition などの IDE 機能が制限される可能性が高いです。
展開してから処理するのは難しいのかな
コンパイラはマクロの実装が元のボディの要素を展開後のどこに配置したのか、そもそも利用したのかの知識がありません。なので仮に @SomeBodyMacro func foo(a: Int, b: Int) { expr }func foo(a: Int, b: Int) { expr let a: String = "" expr } に書き換えられるマクロがあったとき、非常に恣意的な例ですが、 @SomeBodyMacro func foo(a: Int, b: Int) { a.<HERE> } みたいなコード補完だと、a が Int なのか String なのかわからない、みたいな話です。