でピーター・ノーヴィグは言う:
あなたはevalのを使用して自分自身を見つける場合は、「 「現代のLispで...のevalは(実際には、スキームにまったくevalはありません)あまり頻繁に使用されています」たぶん間違ったことをしているのです "。EVALスキーム
スキームでevalを使用して回避する方法は何ですか? evalが絶対に必要なケースがありますか?
でピーター・ノーヴィグは言う:
あなたはevalのを使用して自分自身を見つける場合は、「 「現代のLispで...のevalは(実際には、スキームにまったくevalはありません)あまり頻繁に使用されています」たぶん間違ったことをしているのです "。EVALスキーム
スキームでevalを使用して回避する方法は何ですか? evalが絶対に必要なケースがありますか?
eval
が必要な場合がありますが、常に動的にコードを読み込むような高度なプログラム(Webサーバーのサーブレットなど)が含まれています。あなたが解決しようとしている実際の問題に依存して、それを "回避"する方法としては、eval
を避けるための魔法の解決策はありません... eval
を除きます。
私はスクリプト環境で「のeval」の見てきた
まず、PAIPはSchemeではなくCommon Lispのために書かれているので、私は彼が同じことを言っているかどうかは分かりません。 CLマクロは、eval
と同じことをしますが、実行時ではなくコンパイル時に行うことができますが、他にもできることがあります。 Common Lispでeval
を使用した例を私に示したいのであれば、同じことをする他の方法を考え出すことができます。
私はSchemeプログラマーではありません。私はCommon LispのプログラマーとしてNorvigの観点からしか話すことができません。私は彼がSchemeについて話していたとは思わないし、彼がSchemeをよく知っているかよく知っているか分からない。
第2に、「あなたは間違ったことをしている」よりも、「おそらく間違ったことをしている」とNorvigは言います。これは、彼が知っているすべての人にとって、eval
が正しいことがあることを意味します。 Cのような言語では、私はgoto
について同じことを言っていますが、いくつかの制限された状況では非常に便利ですが、ほとんどはgoto
の方がよく分かりません。
「私は彼が特によくスキームを知っていれば知ってはいけません」。この声明はかなり信じられないほどです。 「evalが正しいことがある時がある」それは私の2番目の質問でした。プログラマーの練習として、evalを使用しましたか? – unj2
明らかに、NorvigはCommon Lispに非常に優れており、本当に優れた本を書いています。これはSchemeには当てはまりません。 Stroustrupは、JavaやObjective-Cで何かをする最良の方法として、必然的に良い権限ですか?その言語ファミリは、Common LispとSchemeを含むLispファミリとは異質なものではありません。 –
hmmm彼はlispのスキームを実装しています。まあ、私は知らない。私は彼が "特によく知っている"スペクトルにあると思うだろう。 – unj2
スキームインタープリタをschemeに書くことができます。これは確かに可能ですが、実用的ではありません。
私は使用されていないスキームを持っているので、これは一般的な答えですが、それでもあなたを助けるかもしれません。 :)
これは、私が欲しかった答えの近くにはありません。 :) – unj2
一つの使用は、いくつかのパラメータを設定することである(ちなみに、私の推測ではeval
スキームレポートに追加された前PAIPは、長い時間前に書かれたということです。)ランタイム値を持つコード。たとえば、擬似C:
param = read_integer();
fn = eval("int lambda(int x) {
int param = " + to_string(param) + ";
return param*x; }");
私はあなたが本当に醜いことを願っています。実行時に文字列を貼り付けてコードを作成しますか? Ick。 Schemeや他の語彙スコープのLispsでは、evalを使わずにパラメータ化された関数を作ることができます。等が挙げられた
(define make-my-fn
(lambda (param)
(lambda (x) (* param x)))
(let* ([ param (read-integer) ]
[ fn (make-my-fn param ])
;; etc.
)
、動的なコードローディングなどがまだ評価必要はなく、パラメータ化されたコード及びコード組成物が第一級関数を用いて製造することができます。
ごくまれに、eval
が必要です。最初に気になるのは、プログラムでプログラムをビルドして実行するときです。これは、例えば遺伝子アルゴリズムを中心に起こります。この場合、実行する必要のあるランダムなプログラムをたくさん作成します。eval
をコードと組み合わせてデータを作ることは、遺伝的アルゴリズムを行う最も簡単なプログラミング言語です。
評価するコードに対してコンパイル時の最適化を行う可能性をすべて排除するため、これらのプロパティを持つことは(プログラムの速度とサイズの点で)非常にコストがかかります。結果のバイナリ。それは避けることができたときにeval
を使用することが貧弱なデザインと考えられている結果
。
Schemeは何eval
を持っていない請求は、少なくともSchemeの標準(後R5RSと)の最新バージョンのために不正確です。通常は、代わりにマクロが必要で、コンパイル時にコードが生成されます。
eval
は避けるべきであることは事実です。手始めに、私は例えば、それがどのように振る舞うべきかを十分に定義を見たことがない:何の環境が渡されていないときに評価されるべきであるどのような環境の表現
私は、eval
を使用するSchemeアプリケーションを使用して、コンパイル時に計算構造がわからない場合に実行時に動的にコードを生成しました。その意図は、にScheme処理系を得るにパフォーマンス上の理由から、難易度のために、実行時にコードをコンパイルすることであったScheme処理系伝えるための標準的な方法がないことである「このコードをコンパイルするには。」
それはeval
は巨大なセキュリティ上のリスクができることも言うまでもないです。 eval
は、ユーザーの入力から離れて巨大な壁を持たないものでは決してありません。基本的には、eval
を安全に使用したい場合は、コンパイルのようなシステムのコード生成段階のコンテキストで、入力を構文解析した後に(包括的に定義された文法を使用して)行う必要があります。
私は、私が質問で欲しかったことについてもっと具体的にすることはできませんでした。しかし興味深いのは、いつもevalが常にSchemeの不可欠な部分だと思っていたことです。とにかく、私はCS G111のevalのより多くの使い方と「乱用」を見て欲しいと思います。 :) – unj2
はい、 'eval' *はSchemeの不可欠な部分ですが、高度なケースでは本当に必要です。経験則は、あなたが 'eval'を使用する必要がある技術的な理由がわからない場合、あなたは*それを必要としません。 (これは深刻な答えです!) いずれにせよ、もしあなたがそれを取るなら、あなたはCSG111の 'eval'ingをたくさん持っています。もし覚えていれば、それについて私に尋ねてください。 –