1

私はClojureを学んでいて、動的スコープで遊んでいます。私はいくつかのことを発見しました:

  • 既存の Var にメタデータを追加{:dynamic true}しても、実際には Var は動的になりません。なぜそうなってほしいのかはなんとなくわかりますが、誤解を招く可能性があります。
  • Var が実際に動的かどうかを確認するには、(.isDynamic #'whatever)
  • Var が動的であるかどうかを変更することはできます (しかし、おそらくそうすべきではありませんか?)(.setDynamic #'whatever)

要するに、Var の動的な性質は clojure.lang.Var クラス自体の内部に格納されているように見え、定義時に^:dynamicメタデータを設定すると、その内部状態にのみ影響します。後でメタデータを変更しても、影響はないようです。いいよ。

名前空間 clojure.core の動的変数を調べていたときに、これを発見しました。:dynamicその名前空間のどの変数にメタデータが設定されているかを確認しました。

user=> (def metadyn (map key (filter #(-> % key resolve meta :dynamic) (ns-publics 'clojure.core))))
#'user/metadyn
user=> metadyn
(*3 *2 *print-level* *data-readers* *e *print-length* *1 *verbose-defrecords*
*clojure-version* *default-data-reader-fn* pr)

思ったよりも少なく、*out*やのようなものがありません*in*でした。

Varsが実際に動的であることを確認しました:

user=> (def realdyn (map key (filter #(-> % key resolve .isDynamic) (ns-publics 'clojure.core))))
#'user/realdyn
user=> realdyn
(*compile-path* *3 *2 *ns* *print-level* *allow-unresolved-vars* *data-readers*
*unchecked-math* *math-context* *read-eval* *compile-files* *command-line-args*
*warn-on-reflection* *e *flush-on-newline* *out* *print-length* *1 *file* *verbose-defrecords*
*clojure-version* *use-context-classloader* *err* *default-data-reader-fn* *agent* pr
*print-dup* *print-readably* *fn-loader* *print-meta* *in* *source-path* *compiler-options* *assert*)

さらに多く。

したがって、次の Var は動的ですが、メタデータにあると主張していません。

user=> (clojure.set/difference (set realdyn) (set metadyn))
#{*compile-path* *ns* *allow-unresolved-vars* *unchecked-math* *math-context* *read-eval*
*compile-files* *command-line-args* *warn-on-reflection* *flush-on-newline* *out* *file*
*use-context-classloader* *err* *agent* *print-dup* *print-readably* *fn-loader* *print-meta*
*in* *source-path* *compiler-options* *assert*}

私の質問は単純です: これには何か意味がありますか? それとも、Clojure の実装で簿記がずさんなだけなのでしょうか?

これは実用的ではありません。理解しようとしているだけです。

4

1 に答える 1