2008年10月1日水曜日

[xyzzy]arglist関数おまけ

もう少し返り値を見やすくする方法に気づいたのでメモ。

こっちのarglistをarglist-1に置き換えて次の関数とマクロを追加

(defun arglist (x)
  (let ((args (arglist-1 x)))
    (if (consp args)
        (nth-value 0 (read-from-string (princ-to-string args)))
      args)))

(defmacro nth-value (n form)
  `(nth ,n (multiple-value-list ,form)))

(arglist-1 'apply)  ; (function lisp::arg &rest lisp::more-args)
(arglist 'apply)    ; (function arg &rest more-args)
(arglist 'if)       ; "TEST THEN [ELSE]"

2008-10-02T19:34:37+09:00 [追記]

ツッコミを入れられたらできるだけ返したくなる性分です。 困ったものです。

ついでなのでpaste.lisp.orgに貼ってみた。変更点は(nth-value ~)あたり。
http://paste.lisp.org/display/67774

これでキーワードシンボルはなるべくそのままにした関数の引数リスト を返してくれる(はず)です。keywordpなんて関数はじめて見た。

ただし、関数引数にキーワードシンボルが入るのは組み込み関数だけのようです。なのでLispで書いたLisp関数の引数はコロンなしのシンボルになります。 この挙動はCLISP,Allegroでも同じみたいなのでこのままで良いかな。

(arglist 'make-list)
(size &key :initial-element)    ; xyzzy
(#:ARG0 &KEY :INITIAL-ELEMENT)  ; clisp
(EXCL::SIZE &KEY EXCL::INITIAL-ELEMENT) ; acl
(arglist (lambda (fn seq &key key1 key2 key3)
           (list key1 key2 key3)))
(fn seq &key key1 key2 key3)    ; xyzzy
(FN SEQ &KEY KEY1 KEY2 KEY3)    ; clisp
(FN SEQ &KEY KEY1 KEY2 KEY3)    ; acl

# xyzzyはmodern(大文字と小文字を区別する)だから :test -> :TEST
# に変換する必要はないのかなあ

2 件のコメント:

  1. 特にありませんけど、あえて挙げるならばキーワードパッケージシンボルのコロンまでなくなってしまうのがあれかもしれません。
    &key があるので分かりますけどね。
    *package* を関数シンボルの symbol-package にあわせて、プリントするとかでいけると思います。

    返信削除
  2. (let ((*package* (symbol-package 'when)))
    ...)
    ということでしょうか。

    #'when->'when の変換が分からなかったので今回は別の方法で直してみました。

    返信削除