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-02-22

#系マクロを考える

| 14:14 | #系マクロを考える - わだばLisperになる を含むブックマーク はてなブックマーク - #系マクロを考える - わだばLisperになる

先日defmacro#という、defmacro!の応用マクロを考えてみましたが、以前に、iglambdaという、これも、#:fooのようなシンボルを利用したマクロを考えていました。

このインターンされないシンボルを利用する路線で色々考えてみました。

let#

destructuring-bindに引数のignore宣言を追加してみました。名前が長いので、letに。#が付いていれば、競合することもないでしょう。

(let# (#:a b &rest #:rest) '(1 2 3 4)
  (list b))
;=> (2)

bind#

multiple-value-bind版です。

(bind# (#:s m #:h #:d #:mo y) (decode-universal-time (get-universal-time))
  (list m y))
;=> (52 2009)

lambda#

以前のiglambdaです。致し方ないとはいえ、funcallしないといけないのが残念。

(mapcar (lambda# (#:x) (gensym))
        '(1 2 3 4 5))
;=> (#:G794417 #:G794418 #:G794419 #:G794420 #:G794421)

(funcall (lambda# (#:a b c) (list b c)) 1 2 3)
;=> (2 3)

defun#

defunでも何かできないかと考えたのですが、引数を無視する需要もあまりないかなと思ったので、dynamic-extent宣言することにしてみました。

今のところ&restのみです。&rest# fooでなく、&rest #:fooの方が良いかも。

(defun# add (&rest# x)
  (apply #'+ x))

(add 1 2 3)
;=>  6

定義

(defmacro lambda# ((&rest bvl-spec) &body body)
  (let ((ignores (remove-if #'symbol-package bvl-spec)))
    `(lambda ,bvl-spec 
       ,@(when ignores `((declare (ignore ,@ignores))))
       ,@body)))

(defmacro bind# (bvl-spec values &body body)
  (let ((ignores (remove-if #'symbol-package bvl-spec)))
    `(multiple-value-bind ,bvl-spec ,values
       ,@(when ignores `((declare (ignore ,@ignores))))
       ,@body)))

(defmacro let# (bvl-spec values &body body)
  (let ((ignores (remove-if #'symbol-package bvl-spec)))
    `(destructuring-bind ,bvl-spec ,values
       ,@(when ignores `((declare (ignore ,@ignores))))
       ,@body)))

(defmacro defun# (name lambda-list &body body)
  (flet ((&rest#-p (x) (string-equal '&rest# x)))
    (let ((dynamic (second (member-if #'&rest#-p lambda-list))))
      `(defun ,name ,(substitute-if '&rest #'&rest#-p lambda-list) 
         ,@(when dynamic `((declare (dynamic-extent ,dynamic))))
         ,@body))))

ゲスト



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