13

値のリストが与えられた場合、すべての要素がNILでない場合はリストをTに減らし、そうでない場合はNILに減らしたいと思います。これは私にエラーを与えます:

(apply #'and (get-some-list))

これがそうであるように:

(reduce #'and (get-some-list))

これは私が思いついた最高のものです:

[11]> (defun my-and (x y) (and x y))
MY-AND

[12]> (reduce #'my-and '(T T T T T))
T

[13]> (reduce #'my-and '(T T T T NIL))
NIL

「#」と「」が無効なのはなぜですか?Common Lispでこれを行うためのより慣用的な方法はありますか?

4

3 に答える 3

21

EVERY関数を使用できます。

(every #'identity '(T T T T T))  ->  T

(every #'identity '(T T T T NIL))  ->  NIL

おそらく最も効率的な方法は、LOOPを使用することです。

(loop for element in '(T T T T nil) always element)  ->  NIL

利点は、リスト要素に対する関数呼び出しが必要ないことです。

#'式の読み取り中にFUNCTIONに展開される読み取りマクロです。#'and(FUNCTION AND)もそうです。

機能はここで説明されています:http ://www.lispworks.com/documentation/HyperSpec/Body/s_fn.htm

FUNCTIONは、関数名またはラムダ式を受け取り、対応する関数オブジェクトを返します。

ANDはここで定義されます: http ://www.lispworks.com/documentation/HyperSpec/Body/m_and.htm

ANDはマクロであり、関数ではないということです。その結果、対応する関数オブジェクトを返すためにFUNCTIONにはマクロではなく関数が必要になるため、(FUNCTION AND)は機能しません。sepp2kが彼の回答で説明しているように、LAMBDAを使用して関数を作成し、その関数内でマクロANDを使用できます。マクロを値として渡すことはできず、後でFUNCALLまたはAPPLYを介して呼び出すことはできません。これは関数でのみ機能します。

このソリューションは次のように記述されます

(reduce (lambda (x y) (and x y)) (get-some-list))

(lambda (...) ...)LAMBDAは、に展開される マクロです(function (lambda (...) ...))

したがって、上記は実際には次のとおりです。

(reduce (function (lambda (x y) (and x y))) (get-some-list))

これは次のように書くことができます

(reduce #'(lambda (x y) (and x y)) (get-some-list))

Common Lispは値と関数の名前空間を区別するため、FUNCTIONが必要です。REDUCEは、関数を引数として値で渡す必要があります。したがって、関数の名前空間から関数を取得する必要があります。これがFUNCTIONの目的です。関数オブジェクトを渡したいときはいつでも、関数名前空間からそれを取得する必要があります。

たとえば、ローカル関数の場合:

(flet ((my-and (x y) (and x y)))
  #'my-and)

Common Lispの設計中に、(FUNCTION(LAMBDA ...))に展開されるコンビニエンスマクロとしてのLAMBDAが追加されました。

于 2010-12-26T21:01:35.597 に答える
10

#'andandは関数ではなくマクロであるため、無効です。

ラムダを使用すると、名前付き関数を定義する必要がなくなります。

(reduce (lambda (x y) (and x y)) (get-some-list) :initial-value t)

しかし、そのような近道はありません#'

everyまたは、ID関数を述語として使用することもできます。

于 2010-12-26T20:21:23.673 に答える
3

'sharp-quote'記号は、通常の関数でのみ使用できます。

Note that only ordinary functions can be quoted with #’. It is an error to
quote a macro function or special function this way, or to quote a symbol with
#’ if that symbol does not name a function.

> #’if
Error: IF is not an ordinary function.

COMMON LISP:シンボリック計算の穏やかな紹介、202ページ

于 2010-12-26T20:28:19.233 に答える