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-11-06

KMRCLを眺める (7) acond

| 01:10 | KMRCLを眺める (7) acond - わだばLisperになる を含むブックマーク はてなブックマーク - KMRCLを眺める (7) acond - わだばLisperになる

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

大体予想は付くと思いますが、AIFのCOND版です。

使われ方としては、

(ACOND ((PROBE-FILE "/etc/foo") IT)
       ((PROBE-FILE "/etc/passwd") IT)
       (T NIL))
;⇒ #P"/etc/passwd"

という感じでしょうか。まったくぱっとした例ではありませんが…。

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

(defmacro acond (&rest clauses)
  (if (null clauses)
      nil
      (let ((cl1 (car clauses))
            (sym (gensym)))
        `(let ((,sym ,(car cl1)))
           (if ,sym
               (let ((it ,sym)) ,@(cdr cl1))
               (acond ,@(cdr clauses)))))))

IFでCONDの定義も一緒にやってる感じなので、ちょっと複雑になってます。

前回に引き続きSchemeでこれで似た感じのものは、condの=>があるでしょうか。

(define (probe-file file-name)
  (and (file-exists? file-name) file-name))

(cond ((probe-file "/etc/foo") => values)
      ((probe-file "/etc/passwd") => values)
      (else #f))

そもそもの例がぱっとしないのでこれもぱっとしませんが、Schemeでは、=>で関数に処理を投げることができますね。

ちなみに、上のコードの例だと、そもそも、ACONDである必要はなくて、

(COND ((PROBE-FILE "/etc/foo"))
      ((PROBE-FILE "/etc/passwd"))
      (T NIL))
;⇒ #P"/etc/passwd"

で書けてしまいます。

しかし、CLtLでは述語の返り値を使うようなスタイルは判りづらいので如何なものかと述べられています。確かにこの例でも何が返り値になるか読み取るのは難しいかもしれません。

さらに脱線ですが、この述語の返り値を割と積極的に使おうとしているマクロにAllegro CLのIF*があります。

もともとは、Franz LispのIFだったものを受け継いだもののようですが、上の例は、

(IMPORT 'ACL-COMPAT.EXCL:IF*)

(IF* (PROBE-FILE "/etc/foo")
     THENRET
ELSEIF (PROBE-FILE "/etc/passwd")
     THENRET
ELSE NIL)
;⇒ #P"/etc/passwd"

と書けます。

THENRETというのがポイントなのですが、これが述語の返り値を返すための指定です。これでCONDと記述力は同じになるわけですね。

…以上、ACONDからどんどん脱線してしまうのでこの辺りでこの辺で切り上げます…。

ゲスト



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