# Lispでスペシャルフォームのorやandをapplyする方法

Date: 2020-05-26
URL: https://s.conao3.com/blog/2020/6e67e4
Author: conao3 (Naoya Yamashita)

`or` や `and` を `apply` したい。

つまり、いろんな操作によって得られたリストに対して `or` や `and` がとりたい。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">なんでこんな面倒なことをしてるんだと思ったら、andがsubrだからapplyできないのか。<br>この問題、CLerはどうやって解決するんだろう <a href="https://twitter.com/hashtag/lisp?src=hash&amp;ref&#95;src=twsrc%5Etfw">#lisp</a> <a href="https://t.co/cmwx3p8ABm">pic.twitter.com/cmwx3p8ABm</a></p>&mdash; Conao3 (@conao&#95;3) <a href="https://twitter.com/conao&#95;3/status/1243861782352912385?ref&#95;src=twsrc%5Etfw">March 28, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">(every #&#39;identity &lt;list&gt;) というのも。</p>&mdash; Shiro Kawai (@anohana) <a href="https://twitter.com/anohana/status/1243863766619410432?ref&#95;src=twsrc%5Etfw">March 28, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

河合さんに `every` を教えてもらいました。

```emacs-lisp
(mapcar #'featurep '(emacs leaf use-package-leaf))
;;=> (t t nil)

(cl-every #'identity (mapcar #'featurep '(emacs leaf use-package-leaf)))
;;=> nil

(cl-every #'identity (mapcar #'featurep '(emacs leaf)))
;;=> t
```

たしかに上手くいっている。 `every` は `and` 相当だったので、 `some` は `or` 相当となる。

```emacs-lisp
(cl-some #'identity (mapcar #'featurep '(emacs leaf)))
;;=> t

(cl-some #'identity (mapcar #'featurep '(use-package-leaf use)))
;;=> nil
```

もちろん、今回の方法はスペシャルフォームではないので、評価してはいけない式が後続している場合、普通にエラーになる。

```emacs-lisp
(or nil t (/ 1 0))
;;=> t

(cl-some #'identity (list nil t (/ 1 0)))
;;=> Debugger entered--Lisp error: (arith-error)
;;     /(1 0)
;;     (list nil t (/ 1 0))
;;     (cl-some (function identity) (list nil t (/ 1 0)))
;;     eval((cl-some (function identity) (list nil t (/ 1 0))) nil)
;;     scratch-comment--elisp--eval-last-sexp(t)
;;     scratch-comment--eval-last-sexp(t)
;;     scratch-comment-eval-sexp()
;;     funcall-interactively(scratch-comment-evalp-sexp)
;;     call-interactively(scratch-comment-eval-sexp nil nil)
;;     command-execute(scratch-comment-eval-sexp)
```
