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 |

2007-09-22


.9

| 15:00 | .9 - わだばLisperになる を含むブックマーク はてなブックマーク - .9 - わだばLisperになる

Maclispのファイルを読んでいて、面白くて理解しやすいファイルがあったので、内容を再現して遊んでみました。

ファイルは、Maclispの「CARCDR.LSP」です。

ファイル名が示すようにこれは、carやcdrのマクロを作成の為のユーティリティのようです。今回は、お題とエラーメッセージだけ頂戴して内容は自分で適当に作りました。

;; def-carcdr

(defmacro def-carcdr (&body exprs)
  `(progn
     ,@(mapcar (lambda (ex)
		 (multiple-value-bind (body name)
		     (compose-CarCdr-expr ex 'lst)
		   `(defun ,name (lst) ,body)))
	       exprs)))

(defun decompose-carcdr-expr (expr)
  (let ((char-lst (map 'list (lambda (x) 
			       (intern (string x)))
		       (string-upcase (string expr)))))
    (or (and (< 7 (length char-lst))
	     (eq 'c (car char-lst)) 
	     (pop char-lst)
	     (eq 'r (car (setq char-lst (nreverse char-lst))))
	     (pop char-lst)
	     (null (remove-if (lambda (x) (or (eq 'a x) (eq 'd x)))
			      char-lst)))
	(error "Invalid name for decompose-CarCdr-expr."))
    (nreverse char-lst)))

(defun compose-carcdr-expr (expr body)
  (values 
   (reduce (lambda (x res)
	     `(,(if (eq 'a x) 'car 'cdr)
		,res))
	   (decompose-CarCdr-expr expr)
	   :initial-value body
	   :from-end 'T)
   expr))
  • 使い方

def-carcdrに定義したいパターンを指定するだけです。複数を一度に定義できます。シンボルのクウォートも必要ありません。

 (def-carcdr
     cadddddaaadadadadaaadaddddaaadddaaddaaadaaddaaddaaddadaadr
     caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar)

(caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar 
 '(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((hello!))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
=> hello!

見ての通り、あまり使いどころはなさそうです。

  • おまけ

Maclispのファイルを読んでいると、関数名に|foo-bar-baz/||や、foo-bar/|という最後に「|」を付けた名前をちらほら見かけます。(/は、Maclispのエスケープ文字なので、Common Lispだと、foo-bar-bar\|に相当)最初これは一体何なんだろうと思っていましたが、この名前を持つ関数は大概、内部的な補助関数のことが多いので、外部から呼ばれることを意図していない関数にこういう名前を付けているようです。%foo-bar-bazというように先頭に%を付けるというのは今の主流かと思いますが、探せば亜流は他にも色々あるのかもしれません。