静的言語が動的言語並の自由度を確保しようと思ったらコード生成は避けれないと思う。
例えばちょっと前にあったdatabaseとの接続もそう。
コンパイル前にスキーマを収集して型を作るのが静的言語における最適解。
それ以外は動的な解決(interface{}を使う)しかなくなり、静的言語としてのメリットを失う。
でも、そもそもコード生成嫌わないで。
生成したコードをデバッグ時に参照できるというのは、バグの解決につながりやすい。
Cで複雑なマクロを組むとエラーがわかりづらくなるけど
プリプロセッサの出力を目視できるようにすると解決できたりする。
だから Goのコード生成もプリプロセッサのコード出力くらいに考えておけばいいと思う。