ふと気づく

Lispのマクロって、DSL的に使う便利さもあるけど、実行環境による差異を吸収するのにも使えるなぁ、ということに気がつく。

twittering-mode.elを作っていて、UCSから文字コードに変換する関数として、ucs-to-charがあるときはucs-to-charを使い、無い場合はdecode-charを使うという処理を実装する必要が出てきた。処理の時に毎回判定コードが走るのはいやだなぁ、と思って考えてみたら、マクロで使う関数を切り替えれば判定コードは一回しか走らなくていいわけだ。

(defmacro twittering-ucs-to-char (num)
  (if (functionp 'ucs-to-char)
      `(ucs-to-char ,num)
    `(decode-char 'ucs ,num)))

コードを記述するときは、twittering-ucs-to-charというUCSから文字コードへの変換関数を呼ぶ感覚で書ける。

判定コードを一回しか走らせない方法としては、JavaScriptの例で、ブラウザを判定してブラウザ依存な処理を行うクロージャを生成する、という方法を見たことがある。Lispの場合それでもいけるけど、わざわざクロージャを生成するよりマクロを使ったほうがいいのかな、という気がする。