Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2009-10-31

KMRCLを眺める (3) aif

| 17:33 | KMRCLを眺める (3) aif - わだばLisperになる を含むブックマーク はてなブックマーク - KMRCLを眺める (3) aif - わだばLisperになる

今日は、KMRCLのmacros.lispの中からAIFです。

AIFはOn Lispでもお馴染のPaul Graham氏作のマクロの中でも、最も有名なものじゃないかと思います。

アナフォリック・マクロの代表という感じですが、アイデアは単純で、テストの結果をitという名前の変数に束縛するというものです。

名前は、Anaphoric IFの略。

使われ方としては、

(AIF (PROBE-FILE "/etc/passwd")
     IT
     (ERROR "No such file or directory"))
;=> #P"/etc/passwd"

みたいな感じでしょうか。

定義はこんな感じです。

;; Anaphoric macros

(defmacro aif (test then &optional else)
  `(let ((it ,test))
     (if it ,then ,else)))

testの内容をitに束縛してるというそのままな内容ですね。

利用上の注意としては、便利だからといってマクロを書くのにAIFを使ったりすると知らぬ間にitが内部で参照できるようなマクロができてしまったりするので、明確な意図がない限りはそういう目的には使わない方が良いのではないかと思います。まあ、当たり前ですね☺

KMRCLを眺める (2) let-if

| 00:37 | KMRCLを眺める (2) let-if - わだばLisperになる を含むブックマーク はてなブックマーク - KMRCLを眺める (2) let-if - わだばLisperになる

毎日KMRCLからマクロ/関数を1つずつだらだらと読んでいこうと思っていましたが、早速2、3日間が空いてしまいました。

let-if

今日は、前回のlet-whenと殆ど同じな、let-ifです。

使われ方としては、

(LET-IF (FILE (PROBE-FILE "/etc/passwd---"))
        FILE
        (PRINT "No such file or directory"))
;=> "No such file or directory"

みたいな感じでしょうか。

マクロ定義はこんな感じです。

(defmacro let-if ((var test-form) if-true &optional if-false)
  `(let ((,var ,test-form))
      (if ,var ,if-true ,if-false)))

そのままですね。

if-falseでnilが束縛されたvarが使いたいかというと、そういうこともあまり無いような気もしますが、使いたいこともあるでしょう。

どういう風にインデントして書くか微妙ですが、とりあえず、IFと同じような感じに揃えてみました。

let-when、when-let、let-if等は、単に並べ替えのマクロなので初めて書いてみたりするマクロとして良いかもしれません。

ちなみに、これらは、Emacs Lispでもそのままのマクロ定義で動くと思います。

※optional引数があるので、Emacs lispでは、(require 'cl)してdefmacro*を使う必要はあるようです。

ゲスト



トラックバック - http://cadr.g.hatena.ne.jp/g000001/20091031