quote or unquote 。。。または、map と apply への関数の与え方?

quote or unquote 。。。または、map と apply への関数の与え方。

 newLISP では、mapapply の引数に関数を与える場合、クォート付き(quote)でも、クォート無し(unquote)でも使えます。

> (map ++ '(1 2 3))
(2 3 4)
> (map '++ '(1 2 3))
(2 3 4)
> (apply + '(1 2 3))
6
> (apply '+ '(1 2 3))
6
> 

 しかし、その違いは何か、ご存知でしょうか?
 私は、正直なところ、「どっちも使えて便利だ」くらいにしか、考えていませんでした(汗)。
 その答えは、“newLISP Fan Club Forum” の記事にあります。
 どう違うかというと、

> (define (sum x) (++ 0 x))
(lambda (x) (++ 0 x))
> (map sum '(1 2 3))
(1 2 3)
> sum
(lambda (x) (++ 0 x))
> (map 'sum '(1 2 3))
(1 3 6)
> sum
(lambda (x) (++ 6 x))
> 

 sum の動作原理は、こちらでどうぞ。それを元に書いた私の blog もあります。
 map だけでなく、apply でも同様です。

> (define (sum x) (++ 0 x))
(lambda (x) (++ 0 x))
> (apply sum '(1))
1
> sum
(lambda (x) (++ 0 x))
> (apply 'sum '(1))
1
> sum
(lambda (x) (++ 1 x))
> 

 さて、何故このような違いが出るのか? その解説も、上記 “newLISP Fan Club Forum” 記事にありますが、一応、説明しましょう。
 関数sum は、引数の値を関数内の ++ の第一引数に加算して保持します(++ が破壊的関数なので関数sum が書き換わる)。
 クォート無しで map(または apply)に渡された関数は、ラムダ式の状態(つまり、無名関数)でリストの要素に適用されます。
 そのため、無名関数が書き換わるだけなので、残りません。
 一方、クォート付きで map(または apply)に渡された関数(つまり、sum というシンボル)は、sum というシンボルに束縛された関数でリストに適用されることになります。
 つまり、書き換わる関数が sum というシンボルに束縛されているので、書き換えた内容が関数 sum 内に残り、加算されて行った訳です。
 まっ、早い話、自己書換関数でない限り、クォートの有無を気にする必要が無いということですが、、、
 さて、話はここで終わりですが、もう一つ例題を

> (delete 'sum)
true
> (define (sum:sum x) (++ 0 x))
(lambda (x) (++ 0 x))
> 

 この場合、デフォルト・ファンクタ sum の動作は、クォートの有無でどう変わるでしょうか?
 答えは、こうなります。

> (map sum '(1 2 3))
(1 3 6)
> (map 'sum '(1 2 3))
(7 9 12)
> 

 クォートの有無に関わらず、同じ動作。何故かは、newLISP ユーザーなら自明ってことで(笑)。

 以上、如何でしょうか?

No comments yet

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google フォト

Google アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。