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 |

2008-07-30

CLで学ぶ「プログラミングGauche」 (9.3)

| 08:05 | CLで学ぶ「プログラミングGauche」 (9.3) - わだばLisperになる を含むブックマーク はてなブックマーク - CLで学ぶ「プログラミングGauche」 (9.3) - わだばLisperになる

9.3 手続きによるパターンの抽象化

9.3は、memberと、deleteと、assocの共通点を括り出してまとめて抽象化してみせるという内容です。

何となくの個人的な感覚ですが、CLというか伝統的なLISPだと、高階関数的に関数で括り出すんじゃなくて、ベタな感じで関数で括り出すかマクロにする傾向が強い気がします。

Schemeを学ぶなら、この辺のところを重点的に学ぶとプログラミング技法的に得られるものも多いんだろうなあという気がしています。

以下CLでさらってみたもの

(defun traverse (fallback get-key return repeat)
  (lambda (elt lst &optional (cmp-fn #'equal))
    (labels ((frob (lst)
                (cond ((endp lst) fallback)
                      ((funcall cmp-fn elt (funcall get-key lst)) (funcall return lst))
                      ('T (funcall repeat #'frob lst)))))
      (frob lst))))

(setf (fdefinition 'member2)
      (traverse () 
                #'car
                #'values
                (lambda (rep lst) (funcall rep (cdr lst)))))

抽象化の手法の違い

CLでは、今回の例のような方法で括り出すよりは、関数を定義するマクロを作ってしまうという割とそのまんまな方法で解決しているコードの方が多い気がします。大同小異ですけれど…。

(use-package :lispworks)

(defmacro define-traverse-function (name &key fallback get-key return repeat)
  (with-unique-names (frob lst)
    `(defun ,name (elt lst &optional (cmp-fn #'equal))
       (labels ((,frob (,lst)
                  (cond ((endp ,lst) ,fallback)
                        ((funcall cmp-fn elt (,get-key ,lst)) (,return ,lst))
                        ('T (,repeat #',frob ,lst)))))
         (,frob lst)))))

(define-traverse-function member2
    :fallback nil
    :get-key car
    :return values
    :repeat (lambda (rep lst) (funcall rep (cdr lst))))

(MEMBER2 'baz '(foo bar baz))
;=> (baz)

ゲスト



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