タグ付けされた質問 「lexical-scoping」

3
レキシカルスコープで「let」が高速になるのはなぜですか?
dolistマクロのソースコードを読んでいると、次のコメントに出会いました。 ;; これは信頼できるテストではありませんが、両方のセマンティクスが許容されるため、重要ではありません。一方は動的スコープでわずかに速く、もう一方はレキシカルスコープでわずかに高速です(そしてより明確なセマンティクスを持ちます)。 これはこのスニペットを参照しています(わかりやすくするために簡略化しています)。 (if lexical-binding (let ((temp list)) (while temp (let ((it (car temp))) ;; Body goes here (setq temp (cdr temp))))) (let ((temp list) it) (while temp (setq it (car temp)) ;; Body goes here (setq temp (cdr temp))))) letループ内で使用されているフォームを見て驚いた。以前setqは、同じ外部変数で繰り返し使用するのに比べて遅いと考えていました(上記の2番目のケースで行われます)。 すぐ上のコメントについては、それが代替よりも高速であると明示的に言っている(レキシカルバインディングを使用している)場合を除いて、私はそれを何もないとして却下したでしょう。だから...それはなぜですか? 上記のコードは、字句バインディングと動的バインディングのパフォーマンスが異なるのはなぜですか? let字句を使用するとフォームが高速になるのはなぜですか?

1
なぜレキシカルスコープのlet-bound変数に対してsetqとset quoteの動作が異なるのですか?
拡張機能の1つにバグがあり、最終的にsetは期待どおりに機能しなかったことが原因であることが判明しました。 ;; -*- lexical-binding: t -*- (let ((a nil)) (setq a t) (print a)) (let ((a nil)) (set 'a t) (print a)) emacs -Q --batch -l temp.elプリントで実行した場合: t nil これは私には非常に奇妙に思えます。私(setq a b)は略記の印象を受けていました(set 'a b)。どうしたの?

3
字句バインディングを使用したlet内のDefunは、「関数が定義されていることが不明です」というバイトコンパイル警告を表示します。
defun内部でlet字句バインディングを使用してクロージャーを作成することにより、静的変数の効果を取得したい。ただし、ファイルをバイトコンパイルすると、警告が表示されます。私は何か間違ったことをしていますか、そうでない場合、この警告を抑制する方法はありますか? MCVEを作成しました: ;; -*- lexical-binding: t -*- (let ((count 0)) (defun increase-count () (interactive) (setq count (1+ count)) (message "Count is: %d" count)) ;; The warning happens here. (increase-count)) コードは期待どおりに機能します。関数increase-countは「Count is:n」を出力します。nは呼び出されるたびに増加します。ただし、このファイルをバイトコンパイルすると、次の警告が表示されます。 In end of data: mcve.el:11:1:Warning: the function ‘increase-count’ is not known to be defined. increase-countletブロックの最後に呼び出される前に、常に定義する必要があるように思えます。そうではありませんか?

1
バッファのレキシカルバインディングを有効にする潜在的な落とし穴は何ですか?
これは、この質問での字句バインディングと字句レットの議論に触発されました。字句結合あなたの人々はあなたがそれをすべての時間を有効になっていないだろう、なぜJavaScriptのような他の言語にするために使用することができる便利なクロージャを持ってすることができますか? 古いEmacsenとの後方互換性は、レガシーコードバッファーで有効にした場合、どのような落とし穴を探す必要があるのか​​を気にしませんか?

1
特定のライブラリーが意図的に欠落している可能性がある場合の「警告:自由変数への割り当て」の処理
私のモードのバイトコンパイル: (defun dict-setup-expansions () "Add `dict-mode' specific expansions." (set (make-local-variable 'er/try-expand-list) (list #'dict-mark-article))) 警告を出します: Warning: assignment to free variable `er/try-expand-list' er/try-expand-list外部で定義されているため、これは正常な状況です。図書館expand-regionにあるhttp://elpa.gnu.org expand-regionライブラリへのモードレジスタ拡張ですが、モードなしでexpand-regionモードを実行しても問題ありません。 警告に対処する適切な方法は宣言を追加することだと思います: (defvar er/try-expand-list) defvar ドキュメントは言う: The `defvar' form also declares the variable as "special", so that it is always dynamically bound even if `lexical-binding' is t. 使用します-*- lexical-binding: …

1
マクロの変数スコープはどのように決定されますか?
で定義されている次のサンプルマクロを見てみましょうmacro.el。 (defmacro some-macro (&rest body) `(let ((some-variable 1)) ,@body)) そして、別のファイルで定義された次の関数を取りますfunction.el。 (defun some-function () (some-macro (do-something))) ときにfunction.elバイトコンパイルされ、うsome-variable字句または動的バインディングでバインドできますか? これはファイルがを使用しているかどうかに依存することを理解している-*- lexical-binding: t; -*-ため、私の質問は特に以下の状況に関係しています。 場合function.el結合が、用途は字句macro.elません。 場合macro.el結合が、用途は字句function.elません。 some-var内部で(defvarを使用して)グローバルに宣言されている場合、違いはありfunction.elますか?もしそうなら、私はそれがそうでない場合に特に興味があります。

3
なぜdefvarスコープはinitvalueなしでは動作が異なるのですか?
次のファイルという名前のファイルがあるとしますelisp-defvar-test.el。 ;;; elisp-defvar-test.el --- -*- lexical-binding: t -*- (defvar my-dynamic-var) (defun f1 (x) "Should return X." (let ((my-dynamic-var x)) (f2))) (defun f2 () "Returns the current value of `my-dynamic-var'." my-dynamic-var) (provide 'elisp-dynamic-test) ;;; elisp-defvar-test.el ends here このファイルをロードしてから、スクラッチバッファーに移動して実行します。 (setq lexical-binding t) (f1 5) (let ((my-dynamic-var 5)) (f2)) (f1 5)期待どおり5を返します。これは、の本体が動的スコープの変数としてf1扱わmy-dynamic-varれていることを示しています。ただし、最後の形式では、にvoid変数エラーが発生しmy-dynamic-var、この変数に字句スコープが使用されていることを示しています。これは、のドキュメントと矛盾しているようですdefvar。 また、defvarフォームは変数を「特別」として宣言するため、たとえlexical-bindingtであっても常に動的にバインドされます。 defvarテストファイルのフォームを変更して初期値を指定すると、ドキュメントに記載されているように、変数は常に動的として扱われます。変数のスコープがdefvarその変数を宣言するときに初期値が提供されたかどうかによって決定される理由を誰かが説明できますか? …

2
url-retrieveからのコールバックにおける「変数としてのシンボルの値はvoid」
次を実行すると、エラーが発生します。 (defun caller (func) (url-retrieve "http://m0smith.freeshell.org/" (lambda (status) (funcall func)))) (caller (lambda() (message "called"))) 結果: error in process filter: Symbol's value as variable is void: func この問題を解決する最良の方法は何ですか?基本的に、どこかからのコールバックを受け入れ、別のラムダでラップし、それをurl-retrieveへのコールバックとして使用する必要があります。 発信者をに変更した場合 (defun caller (func) (url-retrieve "http://m0smith.freeshell.org/" `(lambda (status) (funcall ,func)))) できます。ただし、funcがflycheckによって渡されており、マクロ展開によって中断されるため、これを行うことはできません。私がやっていることの完全なコンテキストを確認するには:https : //gist.github.com/m0smith/b5961fda6afd71e82983
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.