elispイディオム(ブール値と引用符付きの引数)を理解していますか?


7

elispに関する基本的な質問があります。

私はしばしば次のようなものを見ます

(search-forward "something" nil 'noerror)

そして時々私は次のようなものを見ます

(search-forward "something" nil :noerror)

違いは何ですか?他のフォームよりも1つのフォームを優先する必要がありますか?

私が理解している限り、空のリスト以外はブール値のコンテキストではtrueと評価されます。しかし、どうして次のようになります:

「何か」という検索'noerror用語がバッファに存在しない場合、の代わりにを使用すると、ポイントはバッファの最後にジャンプしtます。ときは、tそれがポイントの滞在を使用しています。

最初のケース:

(search-forward "something" nil 'noerror);; 1.Evaluate this

;; end of buffer 2.point jumps here

2番目のケース:

(search-forward "something" nil t);; 1.Evaluate this, 2. Point stays here

;; end of buffer

1
FWIW:nil与えられた関数によってすべての非値が同じように扱われる場合、私のコードでは、関数の説明で使用されているパラメーター名と同じまたは類似の、通常は大文字のシンボルを渡します。これは、コードを読んだときの注意事項です。例えば(search-forward "abc" nil 'NOERROR)。ほとんど使用されないオプションの引数に最も役立ちます。
2015年

回答:


12

elispのブール値は次のように機能します。

  • nilそして、()(あなたが観察したように、同じものです)falseです
  • 絶対に何か他のことが本当です。

t(別の値を使用してしてもメリットはありませんとき)の記号は、真の「純粋な」値として存在するが、ほとんどの機能は、可能な限り、そうでない場合に有用であるかもしれない何かを返すようにしようとします。

こちらもご覧ください C-hig (elisp) nil and t RET

キーワードの引数やその他の記号をnil値以外の値として使用する場合、コード関心を持っているnilかどうかだけを考えるとnil、それは実際には個人の好みの問題です。実行に関しては違いはありません。

私はかつて同じことを尋ねました、そしてキーワード引数アプローチがより一般的なLisp っぽい方法であると知らされました。

(私は、部分的には構文の強調表示のため、そして部分的には変数や関数のシンボルとの区別がより良いために、キーワード引数を自分で使用することにしました。)

特定の例に関して、関数さまざまな非nil値を区別し、その動作はそのdocstringでカバーされています。

オプションの3番目の引数if tは、失敗した場合に返すnil(エラーなし)ことを意味します。そうでない場合はnilt検索範囲に移動して戻りnilます。

一般的に、docstringは「true」や「t」ではなく「non-nil」を参照する傾向があることに気づくでしょう。「t」が表示されている場合は、それが特殊なケースである可能性がかなりあります。


ありがとう、それは私にとってそれを明確にしました!したがって、nil以外はすべてtrueですが、「純粋」としてのtはそれとは異なります。
クレメラ2015年

2
まあ、それはまだシンボルです(自己引用のようなものnilですが)。「純粋」とは、「真」を意味する値であることが明確に存在していることを意味します。ただし、他の非nil値は、すべてのビットが「true」のままtです。
phils 2015年

14

いくつかの歴史的な参照が原因です。

Emacs LispはCommon Lispから多くのものを借りていますが、類似点は表面的な深さのみです。Common Lispのコロン記号は、名前空間修飾子です。正規シンボル名には2つの部分があります。パッケージの名前とそのパッケージ内のシンボルの名前です。たとえば、cl-user:aproposはパッケージで定義されたシンボルcl-userです。起動時にCommon Lispによって自動的にインポートされる特別なキーワードパッケージもあります。このパッケージは、他のパッケージ間の通信に使用されます(そのため、パッケージが相互にシンボリック情報を送信する必要がある場合、それらが誰を宣言する必要があるかを争うことはありません)。ご想像のとおり、そのパッケージのシンボルは先頭にコロンが付いています。

Emacs Lispにはパッケージの概念はありませんが、コロンは、式を自己評価記号として解釈するようにリーダーに指示するという点でまだ特別です(つまり、値はその変数自体である変数です)。:いくつかのような自己評価シンボル内蔵があるtnil私は後で書こうしている例が。

アポストロフィはまた、Common Lispから借用されたもので、標準のリーダーマクロです(つまり、Lispインタープリターがプログラムのソースを読み取るときに実行するコードです)。以下のように拡張する:'x -> (quote x)ここで、(quote ...)式内部の内容を評価からのLispインタプリタを防止する特殊な形態です。Emacs Lispには、リーダーマクロ3を内蔵しています'`そして#、あなたはあなた自身を追加することはできません。最初の2つはに展開され(quote ...)ますが、2番目は未評価の式を構築するための特別な構文を許可します。 フォームに#展開(function ...)され、関数の名前空間で値を検索する必要があることをインタープリターに指示します。

Emacs Lispのシンボルは、(他の言語の変数と同様に)ある値に評価する必要があります。そうでない場合、エラーになります。ただし、見積もりフォームを使用して評価を防ぐことができます。

最後に、以下の違い:

(search-forward "something" nil 'noerror)

そして

(search-forward "something" nil :noerror)

それは、最初のケースsearch-forwardでは名前のみがわかっている値のないシンボルを使用して呼び出し、2番目のケースでは、値がこのシンボル自体であるシンボルを使用してこの関数を呼び出した場合です。たまたま、この関数はどちらを使用するかを気にしません。


タイプは、プログラムの自動検証のための重要なプログラミングツールです。Emacs Lisp型システムは、Common Lispと似ていますが、その汎用型(として記述t)は、他のすべての型の派生元の型です。一方、nilはタイプが派生しないタイプです(の補数t)。これは、汎用型の概念がない、または明確なブール型を持つ多くの一般的なプログラミング言語とは異なります。

またしても、残念ながら、Emacs Lispには、Common Lispのから正確にこの部分をコピーしていなかった、とtype-of関数がための結果を混乱与えますtnil

Emacs Lisp:

(type-of t) ; symbol

Common Lisp

(type-of t) ; BOOLEAN

Emacs Lispの一般的なLisp拡張機能cl-typepには、関係を理解するのに役立つ機能があります。したがって、たとえば

(cl-typep 'noerror t) ; t

つまり、'noerrorそれはタイプtです。


興味深い追加の背景情報、ありがとう!
クレメラ2015年

素晴らしい説明。Common Lispについても学びました。ありがとう。
gsl 2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.