#:g1: (the ignore x)ってどうだろう

Posted 2021-12-11 21:00:56 GMT

Lisp一人 Advent Calendar 2021 12日目の記事です。

手元のネタ帳に『(the ignore x)ってどうだろう』とメモがあるのですが、declaretheの類似性から(the ignore ...)と書けても良いんじゃないか、ということだと思います。
さてどうでしょうか。

手抜き実装では、こんな風に書けるかと思いますが、

(defpackage ignore 
  (:use cl)
  (:shadow the))

(in-package ignore)

(defmacro the (value-type form) (case value-type (cl:ignore (when (typep form 'symbol) `(progn ,form (values)))) (otherwise `(cl:the ,value-type ,form))))

(mapcar (lambda (x y) (the ignore x) y) '(a b c d e) '(0 1 2 3))(0 1 2 3)

そもそもtheは値を返す場所という印象なので、この点でいまいちですね。

ちなみに、古くは、MACLISPやLisp Machine Lispにignoreというのがあり、これと殆ど同じです。
そういえばと思って確認してみたら、Emacs Lispにもありました(interactive関数ですが) さらにちなむと、the形式はInterlisp由来らしいです。

(mapcar (lambda (x y)
          (ignore x)
          y)
        '(a b c d e)
        '(0 1 2 3))(0 1 2 3)

これだったら、λリストで&ignoreとでもした方が便利そうなので、試してみました。

(defun process-&ignore (lambda-list)
  (let ((ignores '()))
    (labels ((collect-&ignore (tree)
               (cond ((null tree) nil)
                     ((consp (car tree))
                      (cons (collect-&ignore (car tree))
                            (collect-&ignore (cdr tree))))
                     ((eq '&ignore (car tree))
                      (push (cadr tree) ignores)
                      (collect-&ignore (cdr tree)))
                     (T (cons (car tree)
                              (collect-&ignore (cdr tree)))))))
      (values (collect-&ignore lambda-list)
              ignores))))

(defmacro fn ((&rest args) &body body) (multiple-value-bind (args ignores) (process-&ignore args) `(lambda (,@args) (declare ,@(if ignores `((ignore ,@ignores)) '())) ,@body)))

(mapcar (fn (&ignore x y) y)
        '(a b c d e)
        '(0 1 2 3))(0 1 2 3)

;; (declare (ignore))を良くつかうところ (set-macro-character #\? (fn (stream &ignore char) `(print ,(read stream T nil T))))

まとめ

&ignoreのほうは、割と使えるかも?
しかし、既存のlambda-list-keywordsでは、基本的にcdr方向全部に指定がかかるので、直後の変数にのみ効くというのは、違和感があるかも。

関連


HTML generated by 3bmd in LispWorks 7.0.0

comments powered by Disqus