14

#' をラムダと一緒に使用する必要があるのはなぜですか? 普段はそのように書かれているので、いい形だと思います。しかし、これらの行は私には等しいようです:

> (mapcar #'(lambda (x) (+ x 1)) '(1 2 3))
(2 3 4)
> (mapcar (lambda (x) (+ x 1)) '(1 2 3))
(2 3 4)

初心者に違いを教えてくれる人はいますか?

4

2 に答える 2

14

さまざまな Lisp の方言で異なります。以下はCommon Lispを使用しています:

最初 の #' は (function ...) の短い表記です。したがって、以下はテキストが異なるだけですが、Common Lisp はそれらを同じものとして読み取ります。

#'(lambda (x) (* x 2))

(function (lambda (x) (* x 2)))

#' は readmacro であり、Lisp コードが Lisp システムによって読み取られるときに変換されます。

Lispが評価する場合

(function (lambda (x) (* x 2)))

Lisp システムは関数オブジェクトを作成し、FUNCTION はそれを値として返します

したがって、関数を値として必要とするときはいつでも、そのように記述する必要があります。値としての関数は、引数として別の関数に渡したい場合、関数から戻りたい場合、または変数に格納したい場合に必要です。例:

(map #'(lambda (x) (* x 2)) '(1 2 3))

(defun (y) #'(lambda (x) (* x y)))

(defparameter *twice-fn* #'(lambda (x) (* x 2)))

さて、 (lambda (x) (* x 2)) とは何でしょう?

文脈に応じて2つの異なるものです。

ラムダ式

関数名の代わりにラムダ式を使用できます。

(function foo)   and    (function (lambda (x) (* x 2)))

(foo 17)    and  ((lambda (x) (* x 2)) 17)

上記の 2 つは、正当な Common Lisp 構文です。ラムダ式を直接使用できます。

次の 2 つの形式は、Common Lisp では不正であることに注意してください。

(#'(lambda (x) (* x 2)) 17)   ; illegal in Common Lisp

(function #'(lambda (x) (* x 2)))  ; illegal in Common Lisp

大きい

Common Lisp の標準化プロセス中に、マクロ LAMBDA が追加されました (これは、Common Lisp の最初の記述である CLtL1 の一部ではありませんでした)。少し短いコードを書くことが可能になります。例:

(lambda (x) (* x 2))

上記の場合、LAMBDA はマクロです。マクロ展開中、次のように展開されます。

(function (lambda (x) (* x 2)))

上記の FUNCTION 形式では、内側のラムダはラムダ式の一部であり、関数を示し、展開されないことに注意してください。

したがって、上記の 3 つの例は次のように記述できます。

(map (lambda (x) (* x 2)) '(1 2 3))

(defun (y) (lambda (x) (* x y)))

(defparameter *twice-fn* (lambda (x) (* x 2)))

これは少し短く、見た目が少しすっきりしていて、Scheme コードに少し似ています。これは、Scheme コードの読み書きに慣れているプログラマにとっては、少しだけ改善されているように見えます。

概要

a) (function (lambda (x) (* x 2))) は、関数を値として返すコードを記述する「真の」方法です。

b) #'(lambda (x) (* x 2)) は上記の短縮表記

c) (lambda (x) (* x 2)) はさらに短いですが、マクロ展開を使用して a) の形式を作成します。

于 2009-05-26T07:01:30.527 に答える