29187


`(add-hook 'hook-name
'hoge)`などで変数名がクオートのみのもの（`'hoge`）とシャープのついたもの（`#'hoge`）を見かけますが、違いは何でしょうか。  
またこれはEmacs Lisp特有でしょうか。


CC BY-SA 3.0
2016-09-27T09:53:35.030
29185
2016-09-28T04:49:02.433
3974
question
elisp lisp
Elispで変数を指定する際 'hoge と #'hoge の違いとは


まず、クオートは、(quote hoge)の略記、シャープクォートは、 (function hoge) の略記になります。  
この、'hoge (quote hoge) と #'hoge (function hoge) の違いはEmacs 特有ではありません。  
最初期のLISPである、LISP 1.5 から連綿と受け継がれているものです。

詳しく書くととても長くなるので、大きく2つに分けて、乱暴に箇条書きにしてしまうと、

### Quote vs Function スコープ篇

  1. 初期のLISP (1959年)で関数を引数にした場合意図しない動作となることが指摘される
  2. LISP 1.5では、上記に対応するため、`function`と`funarg`を導入し、`quote`と使い分けるが、本当に実現したかったものは、Schemeのようにレキシカルスコープを持つ方式だった
  3. Common Lispや最近のEmacs 24ではレキシカルスコープが利用できるようになった

等々ですが、Common Lispと最近のEmacs
Lispでは、`quote`と`function`は、レキシカルスコープで書かれた場合に違いがでてきます。  
具体的には、

  * クロージャーを作る(quoteだと作れない)
  * ローカル関数等を作る

ですが、Emacs Lispにはローカル関数がありませんので、前者の違いのみだと思います。

### Quote vs Function 束縛アクセスの戦略篇

なぜEmacs Lispで`quote`や`function`が殆ど同じような動作になってしまったかというと、Emacs
Lispの先祖のMACLISPがクロージャーのようなものは重視せず、処理系の速度向上を図ったためです。  
当時の実用的なプログラミングスタイルでは、クロージャーが多用されることは考えられておらず、そこをきちんと処理して遅くなるよりは、別の部分の速度や効率を向上させよう、という選択です。

MACLISPを先祖に持つCommon
Lispではレキシカルスコープが採用されたため、クロージャーもサポートされることになるのですが、Schemeとは違い、付け足した感じは否めません。  
奇しくも、Emacs Lispも後付けで、lexical-binding が導入されることとなり、Common Lispと似たような状況になっています。

## 実際のコードでの動作の違い

Emacsでの`quote`と`function`の違いですが、Emacs 24以降のlexical-
binding宣言がある`lambda`の場合に動作が違ってきます。

[code]

    ;; -*- lexical-binding: t -*-
    
    (fset 'ffun
          (let ((x 0))
            #'(lambda ()
                (setq x (1+ x))
                x)))
    
    (fset 'qfun
          (let ((x 0))
            '(lambda ()
              (setq x (1+ x))
              x)))
    
[/code]

をファイルに書いて、M-x load-file し、

`(qfun)`と`(ffun)`を実行してみると、qfunの方ではクロージャーが作れないことが分かります。  
これは、quoteの方は単なるリストだからで、functionでなければクロージャーを作ることはできません。

## コーディングスタイル

Common Lispでは、関数は、`#'foo` と書くことが多いと思いますが、`'foo` でも間違いではありません。  
`#'foo`と記述した方が効率良くコンパイルできたり、エラーが発見しやすくなることはあると思います。

`lambda`に関しては、Emacs Lisp、Common Lispともに`(lambda (x) x)`と書くと、`#'(lambda (x)
x)`に展開されるマクロになっています。  
Common Lispでは`lambda`には`#'`は付けないことが多いようです。また、Emacs
Lispと違って`#'`の代わりに`'`を使うことはできません。

## 参考

  * [function の役割り](http://www.mew.org/~kazu/doc/elisp/function.html)
  * [The Influence of the Designer on the Design — J.McCarthy and LISP](https://web.archive.org/web/20061029131004/http://www8.informatik.uni-erlangen.de/html/lisp/mcc91.html)
  * [クロージャ再考](http://qiita.com/pebblip/items/2ed30f59cd5981513908)


CC BY-SA 3.0
2016-09-27T13:33:22.390
29187
2016-09-28T04:49:02.433
2016-09-28T04:49:02.433
3510
3510
29185
answer