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 |

2010-09-01

重なったフィルターをLISPで左から右に簡潔で読み易く書きたい

| 22:28 | 重なったフィルターをLISPで左から右に簡潔で読み易く書きたい - わだばLisperになる を含むブックマーク はてなブックマーク - 重なったフィルターをLISPで左から右に簡潔で読み易く書きたい - わだばLisperになる

以前から良く考える問題ではあるのですが、今日、

(defun PARENTHIZE (str)
  (let ((rstr (reverse str)))
    (ppcre:regex-replace-all 
     "\\s"
     (write-to-string 
      (reduce (lambda (acc x)
                (cons x (list acc)))
              (subseq rstr 1)
              :initial-value (list (char rstr 0)))
      :pretty nil
      :escape nil)
     "")))
(PARENTHIZE "いろはにほへとちりぬるを")
;⇒ "(い(ろ(は(に(ほ(へ(と(ち(り(ぬ(る(を))))))))))))"

という非常にどうでも良い関数を書いていて、処理の流れが括弧の内側から外側に向っていくのが、やっぱりよみにくいかなあと思い、上手く書ける記法はないかと、色々考えてみました。

こんな風に書けば良いのか

(defun PARENTHIZE (str)
  (let* ((* (reverse str))
         (* (reduce (lambda (acc x)
                       (cons x (list acc)))
                     (subseq * 1)
                     :initial-value (list (char * 0))))
         (* (write-to-string * :pretty nil :escape nil))
         (* (ppcre:regex-replace-all "\\s" * "")))
    *))

こんなマクロを書いてみれば良いのか

(defmacro SEQ (&body body)
  `(LET* (,(mycl-util:group body 2))
     ,(car (last body 2))))
(defun PARENTHIZE (str)
  (seq
    * (reverse str)
    * (reduce (lambda (acc x)
                (cons x (list acc)))
              (subseq * 1)
              :initial-value (list (char * 0)))
    * (write-to-string * :pretty nil :escape nil)
    * (ppcre:regex-replace-all "\\s" * "")))

いや、やっぱりこう書けた方が編集には都合が良いか

(defun PARENTHIZE (str)
  (seq
    (* (reverse str))
    (* (reduce (lambda (acc x)
                 (cons x (list acc)))
               (subseq * 1)
               :initial-value (list (char * 0))))
    (* (write-to-string * :pretty nil :escape nil))
    (* (ppcre:regex-replace-all "\\s" * ""))))

いやいや、いっそこう書けた方が良いか

(defun PARENTHIZE (str)
  (seq
    (reverse str) => *
    (reduce (lambda (acc x)
              (cons x (list acc)))
            (subseq * 1)
            :initial-value (list (char * 0))) => *
    (write-to-string * :pretty nil :escape nil) => *
    (ppcre:regex-replace-all "\\s" * "")))

こういうフィルターを順次重ねてゆく感じの場面で、左から右に良い感じで記述できるような記法/マクロがあったら教えて欲しいです。