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-03-05

クラスを<foo>と表記する試み

| 11:34 | クラスをと表記する試み - わだばLisperになる を含むブックマーク はてなブックマーク - クラスをと表記する試み - わだばLisperになる

DylanやSchemeだとクラスを<foo>の様に表記しますが、CLでこれを真似すると

(defclass <foo> () ())

(make-instance '<foo>)

となります。

若干無駄な抵抗で

(defclass :<foo> () ())

(make-instance :<foo>)

というのもありかもしれません。ちょっと問題がありますが…。

結局のところ<foo>は自己評価型のシンボルでもなんでもないのでこういうことになるのですが、quoteを付けなくてもよいようにできないものかなとリーダーマクロでごちゃごちゃ遊んでみました。

内容としては、<foo>というシンボルを読んだときに、symbol-valueに<foo>を詰めこんでしまうというもので副作用メインのリーダーマクロです。

'|'でのエスケープについては考えたのですが、そういえば、バックスラッシュの対応は忘れてしまいました。

パッケージ内で有効なキーワードのようなものがあれば、こういう目的に使えるのかもしれません。

何か手軽で良い方法があったら是非教えてくださいー。

(defun white-char-p (ch)
  (not (null (member ch '(#\Space #\Tab #\Newline)))))

(set-macro-character #\< 
                     (lambda (stream char)
                       (let ((ch (read-char stream)))
                         (if (white-char-p ch)
                             '<
                             (progn
                               (unread-char ch stream)
                               (do ((res (list char))
                                    (in-barp 0)
                                    (ch (read-char stream)
                                        (read-char stream)))
                                   ((eql #\> ch) 
                                    (let ((sym (intern
                                                (coerce (nreverse (push #\> res))
                                                        'string))))
                                      (setf (symbol-value sym) sym)
                                      sym))
                                 (if (eql #\| ch)
                                     (incf in-barp)
                                     (PUSH (if (oddp in-barp)
                                               ch
                                               (char-upcase ch))
                                           RES))))))))

動作

(< 2 3)
;=> T

;; 上の定義だと結局エスケープしないといけない(中途半端)
(\<= 2 3)
;=> T

(progn
  <z|ot|>)
;=> |<Zot>|

(defclass <qqq> () ())
;=> #<STANDARD-CLASS <QQQ>>

(make-instance <qqq>)
;=> #<<QQQ> {100E2D2C91}>

(defclass <foo|bar|baz> () ())
;=> #<STANDARD-CLASS <FOObarBAZ>>

(make-instance <foo|bar|baz>)
;=> #<<FOObarBAZ> {100E2D2C98}>

ゲスト



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