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-10-17

TAOの!再び

| 03:08 | TAOの!再び - わだばLisperになる を含むブックマーク はてなブックマーク - TAOの!再び - わだばLisperになる

以前からTAOの!についてCommon Lispで再現すべく色々考えてみたりしていましたが、

TAOでは!文字の解釈が

  • SETF的な!
(let (x)
  (!x 30)
  x)
;⇒ 30
  • 自己投入式(Algol系言語でいう x += 1のような表現)
(let ((x 0) (y 1))
  (!!+ 30 y !x)
  x)
;⇒ 31
  • ORにバックトラック機能がついたようなもの(詳細不明:Prolog風らしい)
(! _x _y)

Prolog的な構文でのカット記号

(assertz (p a1..) ... B2 ! B3 ...)
  • cdr!: (setq list (cdr list))と同じ
(cdr! list)

と色々あるので、なかなか!をマクロ文字にする方法では全部を簡単に解決できません。

ということで、今度は開き括弧の方に細工をしてみようということで、ちょっと書いてみました。

Named Readtablesが面白そうだったので意味なく使ってみています。

(IN-PACKAGE :TAO-COMPAT)

(DEFUN TAO-READ-LIST (STREAM IGNORE)
  (CASE (PEEK-CHAR T STREAM)
    ((#\!) (READ-CHAR STREAM)
     (CASE (PEEK-CHAR NIL STREAM)
       ((#\Space #\Newline #\Return #\Tab)
        (READ-CHAR STREAM)
        `(OR ,@(SB-IMPL::READ-LIST STREAM IGNORE)))
       ((#\!) 
        (READ-CHAR STREAM)
        `(TAO-COMPAT:SELFASS 
          ,@(SB-IMPL::READ-LIST STREAM IGNORE)))
       (OTHERWISE 
        `(SETF ,@(SB-IMPL::READ-LIST STREAM IGNORE)))))
    (OTHERWISE
     (SB-IMPL::READ-LIST STREAM IGNORE))))

;;;
;;;
(IN-PACKAGE :CL-USER)
(USE-PACKAGE :NAMED-READTABLES)

(DEFREADTABLE :TAO-COMPAT
  (:MERGE :STANDARD)
  (:MACRO-CHAR #\( #'TAO-COMPAT::TAO-READ-LIST 'T)
  (:CASE :UPCASE))
(IN-READTABLE :COMMON-LISP)

(LET ((X (LIST 1 2 3)))
  (!!CDR !X))
;>>> error

(IN-READTABLE :TAO-COMPAT)

(! FOO BAR BAZ) ;(OR FOO BAR BAZ)に展開される

(LET ((X (LIST 1 2 3)))
  (!!CONS 'HEAD !X)
  X)
;⇒ (HEAD 1 2 3)

(LET ((X (LIST 1 2 3)))
  (!(CAR X) 'HEAD)
  X)
;⇒ (HEAD 2 3)

;; incf的
(LET ((X 0))
  (!!1+ !X)
  X)
;⇒ 1

(IMPORT 'TAO-COMPAT:CDR!)

(LET ((X (LIST 1 2 3)))
  (CDR! X)
  X)
;⇒ (2 3)

(!(SYMBOL-FUNCTION 'FOO) (LAMBDA (X) X))

(FOO 3)
;⇒ 3

やはりこの場合は、開き括弧の文字に定義されている関数を再定義する方が綺麗にできるようです。

括弧の意味の再定義はなんとなく抵抗がありますが…。