2009-06-25 10 views
5

でピーター・ノーヴィグは言う:
あなたはevalのを使用して自分自身を見つける場合は、「 「現代のLispで...のevalは(実際には、スキームにまったくevalはありません)あまり頻繁に使用されています」たぶん間違ったことをしているのです "。EVALスキーム

スキームでevalを使用して回避する方法は何ですか? evalが絶対に必要なケースがありますか?

答えて

7

evalが必要な場合がありますが、常に動的にコードを読み込むような高度なプログラム(Webサーバーのサーブレットなど)が含まれています。あなたが解決しようとしている実際の問題に依存して、それを "回避"する方法としては、evalを避けるための魔法の解決策はありません... evalを除きます。

私はスクリプト環境で「のeval」の見てきた

+0

私は、私が質問で欲しかったことについてもっと具体的にすることはできませんでした。しかし興味深いのは、いつもevalが常にSchemeの不可欠な部分だと思っていたことです。とにかく、私はCS G111のevalのより多くの使い方と「乱用」を見て欲しいと思います。 :) – unj2

+1

はい、 'eval' *はSchemeの不可欠な部分ですが、高度なケースでは本当に必要です。経験則は、あなたが 'eval'を使用する必要がある技術的な理由がわからない場合、あなたは*それを必要としません。 (これは深刻な答えです!) いずれにせよ、もしあなたがそれを取るなら、あなたはCSG111の 'eval'ingをたくさん持っています。もし覚えていれば、それについて私に尋ねてください。 –

1

まず、PAIPはSchemeではなくCommon Lispのために書かれているので、私は彼が同じことを言っているかどうかは分かりません。 CLマクロは、evalと同じことをしますが、実行時ではなくコンパイル時に行うことができますが、他にもできることがあります。 Common Lispでevalを使用した例を私に示したいのであれば、同じことをする他の方法を考え出すことができます。

私はSchemeプログラマーではありません。私はCommon LispのプログラマーとしてNorvigの観点からしか話すことができません。私は彼がSchemeについて話していたとは思わないし、彼がSchemeをよく知っているかよく知っているか分からない。

第2に、「あなたは間違ったことをしている」よりも、「おそらく間違ったことをしている」とNorvigは言います。これは、彼が知っているすべての人にとって、evalが正しいことがあることを意味します。 Cのような言語では、私はgotoについて同じことを言っていますが、いくつかの制限された状況では非常に便利ですが、ほとんどはgotoの方がよく分かりません。

+0

「私は彼が特によくスキームを知っていれば知ってはいけません」。この声明はかなり信じられないほどです。 「evalが正しいことがある時がある」それは私の2番目の質問でした。プログラマーの練習として、evalを使用しましたか? – unj2

+1

明らかに、NorvigはCommon Lispに非常に優れており、本当に優れた本を書いています。これはSchemeには当てはまりません。 Stroustrupは、JavaやObjective-Cで何かをする最良の方法として、必然的に良い権限ですか?その言語ファミリは、Common LispとSchemeを含むLispファミリとは異質なものではありません。 –

+0

hmmm彼はlispのスキームを実装しています。まあ、私は知らない。私は彼が "特によく知っている"スペクトルにあると思うだろう。 – unj2

-1

スキームインタープリタをschemeに書くことができます。これは確かに可能ですが、実用的ではありません。

私は使用されていないスキームを持っているので、これは一般的な答えですが、それでもあなたを助けるかもしれません。 :)

+0

これは、私が欲しかった答えの近くにはありません。 :) – unj2

4

彼は間違っています。もちろん、Schemeにはevalがあります。

+0

どのスキームですか?私はr4rsがevalが全く存在する必要はないと思う。 – Aaron

+3

R5RS http://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.5 – newacct

+3

@newacct PAIPは1992年に発売され、R4RSには評価がありませんでした。 R5Rsは1998年に来て、評価、動的風と価値を追加しました:) – Sylwester

0

一つの使用は、いくつかのパラメータを設定することである(ちなみに、私の推測では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. 
) 

、動的なコードローディングなどがまだ評価必要はなく、パラメータ化されたコード及びコード組成物が第一級関数を用いて製造することができます。

3

ごくまれに、evalが必要です。最初に気になるのは、プログラムでプログラムをビルドして実行するときです。これは、例えば遺伝子アルゴリズムを中心に起こります。この場合、実行する必要のあるランダムなプログラムをたくさん作成します。evalをコードと組み合わせてデータを作ることは、遺伝的アルゴリズムを行う最も簡単なプログラミング言語です。

評価するコードに対してコンパイル時の最適化を行う可能性をすべて排除するため、これらのプロパティを持つことは(プログラムの速度とサイズの点で)非常にコストがかかります。結果のバイナリ。それは避けることができたときにevalを使用することが貧弱なデザインと考えられている結果

3

Schemeは何evalを持っていない請求は、少なくともSchemeの標準(後R5RSと)の最新バージョンのために不正確です。通常は、代わりにマクロが必要で、コンパイル時にコードが生成されます。

evalは避けるべきであることは事実です。手始めに、私は例えば、それがどのように振る舞うべきかを十分に定義を見たことがない:何の環境が渡されていないときに評価されるべきであるどのような環境の表現

  1. 環境に合格すると、どのように機能しますか?たとえば、標準では、その環境オブジェクトの値をあらかじめバインドすることはできません。

私は、evalを使用するSchemeアプリケーションを使用して、コンパイル時に計算構造がわからない場合に実行時に動的にコードを生成しました。その意図は、にScheme処理系を得るにパフォーマンス上の理由から、難易度のために、実行時にコードをコンパイルすることであったScheme処理系伝えるための標準的な方法がないことである「このコードをコンパイルするには。」

それはevalは巨大なセキュリティ上のリスクができることも言うまでもないです。 evalは、ユーザーの入力から離れて巨大な壁を持たないものでは決してありません。基本的には、evalを安全に使用したい場合は、コンパイルのようなシステムのコード生成段階のコンテキストで、入力を構文解析した後に(包括的に定義された文法を使用して)行う必要があります。