問題タブ [dynamic-scope]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
javascript - Javascript での動的スコープのような奇妙な動作
テスト用に次のコードがあります。
node.jsで実行したときの結果は
で名前variable_function
が解決されるとdynamic_scoped_function
、呼び出し元のスタックに依存するようですが、期待どおりに外側のスタックに静的に解決されません。
dynamic_scoped_function
私の意見では、どこで呼び出されるかを予測できないため、この動作はばかげています。この言語はそのように動作するように設計されていますか? それとも、単に何かを誤解しただけですか?
ご協力いただきありがとうございます。
scope - パラメータで変数をシャドウしない PicoLisp 関数の書き方
私は PicoLisp をぼんやりと調べていて、伝統的に (他の Lisp 方言では) マクロで処理されるメタプログラミング関数をどのように書くかについて困惑していることに気づきました。私にとって最大の懸念は、変数名のシャドウイングを防ぐ方法がわからないことです。Metaprogramming 101の例を確認すると、どちらかといえば、私はさらに混乱したままになりました。
mapeach
リンクされた記事に見られるように、関数を実装する方法の例:
これらのそれぞれを call でテストしました(let "Args" * (mapeach N (1 2 3) ("Args" N N)))
。予想どおり、PicoLisp インタープリター (コマンドで開始pil +
) はセグメンテーション違反を経験し、クラッシュします。これは、 がコール ポイントで定義されたものをシャドウするためmapeach
だと思います。"Args"
"Args"
map@
また、 (の「よりかわいい」代替)の両方の実装を試しましmapeach
た。
私(let "Args" * (map@ (1 2 3) ("Args" @ @)))
はこれらの実装のそれぞれをテストしていました。奇妙なことに、最初の実装を初めてテストしたとき、segfault が発生しなかっただけでなく、実際に正しい結果が生成されました(1 4 9)
。その後の各テストでは、segfault が発生しました。明確にするために、プロンプトからのスニペット:
セグメンテーション違反は、(当時)未定義の関数への呼び出しによって何らかの形で防止されたと思います。mapeach
私も試し(ooga booga)
てみましたが、同様にセグメンテーション違反を防止しました。定義を適切な呼び出しから分離する誤った呼び出しがない場合、segfault は常に発生します。
これは最終的に 2 つの質問で最高潮に達します。
- 名前のシャドウイングを防ぐにはどうすればよいですか? 明らかに、例はその点で成功していません。
- map@ へのその呼び出しがsegfault にならないのはなぜですか?
python - 関数が呼び出し元のスコープを使用する必要があることを宣言する方法はありますか?
C マクロに似た機能があり、そのコードに対して別のスコープを作成せずにインラインでコードを再利用できますか?
例えば:
3を印刷しますが、4を印刷したいです。
クラスやグローバル辞書などのオブジェクトを含むソリューションを認識していますが、代わりに呼び出し元のスコープ内で変更を加えるだけの、より原始的なソリューション (関数デコレーターなど) を探しています。
どうもありがとうございます
編集:どの変数を使用するかを宣言する必要があるか、変更可能なオブジェクトのような「名前空間」を事前に宣言する必要があるソリューションは、私が探しているソリューションではありません。
私は自分で試みました:
しかし、プログラムのデバッグ可能性を損なうことなくコードを挿入する方法について深刻な問題に遭遇しましたstrip_game
。これは、新しいコード オブジェクトを作成するか、exec を使用することしか考えていなかったため、どちらもいくつかの深刻な問題に苦しんでいたためです。
主な編集:
わかりましたので、実用的な解決策に近いものがありますが、非常に奇妙な問題が発生します:
これはうまくいくようですが、次のようになります:
関数を逆アセンブルすると、 と の間に次の非常に奇妙なコンパイルの違いが表示game
されstrip_game
ます。
ゲームで:
ストリップゲームで:
なぜこの違いが生じるのですか?