関数型プログラミングの支持者は、Code Completeでこのステートメントにどのように答えますか?


30

Steve McConnellは、第2版の839ページで、プログラマーが大きなプログラムで「複雑さを克服する」ためのすべての方法について議論しています。彼のヒントは次のステートメントで終わります。

「オブジェクト指向プログラミングは、アルゴリズムとデータに同時に適用される抽象化のレベルを提供します。これは、機能分解だけでは提供されない一種の抽象化です。」

「複雑さを軽減することは、間違いなく効果的なプログラマーになるための最も重要な鍵」(同じページ)という彼の結論と相まって、これは関数型プログラミングへのほとんどの挑戦のようです。

FPとOOの間の議論は、並行性または並列化の課題に特に由来する複雑性の問題に関するFPの支持者によってしばしばフレーム化されます。ただし、ソフトウェアプログラマが克服する必要があるのは、同時性だけではありません。おそらく、ある種の複雑さを減らすことに焦点を合わせると、他の次元では大幅に増加するため、多くの場合、ゲインはコストに見合うものではありません。

FPとOOの比較の条件を、並行性や再利用性などの特定の問題からグローバルな複雑さの管理にシフトした場合、その議論はどのように見えるでしょうか?

編集

私が強調したかったのは、オブジェクト指向はデータとアルゴリズムの両方の複雑さをカプセル化して抽象化しているように見えますが、関数型プログラミングはデータ構造の実装の詳細をプログラム全体に「公開」することを奨励しているようです。

たとえば、ここで「データ型の過剰な指定」は「慣用的なOOスタイルの否定的な結果」であり、AddressBookをより豊富なOOオブジェクトではなく単純なベクトルまたはマップとして概念化することを推奨するStuart Halloway(Clojure FP支持者)を参照してください追加の(非ベクター的かつ非マップ的)プロパティとメソッドがあります。(また、オブジェクト指向およびドメイン駆動設計の支持者は、AddressBookをベクトルまたはマップとして公開すると、カプセル化されたデータがドメインの観点からは無関係または危険なメソッドに過度に露出されると言うかもしれません)。


3
+1は質問がかなり対立的に組み立てられているにもかかわらず、良い質問です。
マッテンツ

16
多くの回答で述べられているように、関数型分解と関数型プログラミングは2つの異なる獣です。したがって、「これは関数型プログラミングへの挑戦と思われる」という結論は明らかに間違っており、それとは何の関係もありません。
ファビオフラカッシ

5
明らかに、最新の機能データ型システムと高次のファーストクラスモジュールに関するMcConnelの知識は、やや不明瞭です。彼の声明はまったくナンセンスです。最初のクラスのモジュールとファンクター(SMLを参照)、型クラス(Haskellを参照)を持っているからです。オブジェクト指向の考え方は、敬意を表した設計方法論よりも宗教である方法の別の例にすぎません。ところで、並行性についてこのことをどこで知りましたか?ほとんどの関数型プログラマーは、並列性をまったく気にしません。
SKロジック

6
@ SK-logic All McConnellによると、「機能分解のみ」ではOOPと同じ抽象化手段が提供されないため、私にとってはかなり安全な声明です。彼は、FP言語にはOOPほど強力な抽象化手段がないとは言っていません。実際、彼はFP言語についてはまったく言及していません。それはただのOPの解釈です。
sepp2k

2
@ sepp2k、わかりました、わかりました。それでも、モジュールの動作をシミュレートすることにより、ほぼ純粋なラムダ計算の機能的な分解に加えて、データ構造と処理抽象化の非常に複雑で階層化されたシステムを構築できます。オブジェクト指向の抽象化はまったく必要ありません。
SKロジック

回答:


13

この本は20年以上にわたって書かれたものであることを忘れないでください。当時のプロのプログラマーにとって、FPは存在しませんでした-それは完全に学者と研究者の領域にありました。

作業の適切なコンテキストで「機能分解」を組み立てる必要があります。著者は関数型プログラミングについて言及していません。これを「構造化プログラミング」とGOTOそれ以前の混乱に結び付ける必要があります。参照点が関数を持たない古いFORTRAN / COBOL / BASICであり(幸運にも単一レベルのGOSUBを取得できた場合)、すべての変数がグローバルであり、プログラムを分解できる場合機能の層への大きな恩恵です。

OOPは、この種の「機能の分解」をさらに改良したものです。命令を関数にまとめることができるだけでなく、関連する関数を作業中のデータでグループ化できます。その結果、明確に定義されたコードの一部が得られ、コードベース全体を追ってデータを操作する可能性のあるものを見つける必要なく、(理想的には)見て理解することができます。


27

関数型プログラミングの支持者は、ほとんどのFP言語が「関数分解のみ」よりも抽象化の手段を提供すると主張し、実際にオブジェクト指向言語のそれに匹敵する抽象化の手段を許可すると想像するでしょう。たとえば、そのような抽象化の手段として、Haskellの型クラスまたはMLの高階モジュールを引用できます。したがって、ステートメント(関数型プログラミングではなく、オブジェクト指向と手続き型プログラミングに関するものであると確信しています)は、それらには適用されません。

FPとOOPは直交する概念であり、相互に排他的ではないことも指摘する必要があります。したがって、それらを互いに比較することは意味がありません。「命令型OOP」(Javaなど)と「機能的OOP」(Scalaなど)を非常によく比較できますが、引用した文はその比較には適用されません。


10
+1 "機能分解"!= "機能プログラミング"。1つ目は、継承、カプセル化、および多相性がない(または手巻きのみ)バニラデータ構造を使用した従来のシーケンシャルコーディングに依存しています。2番目は、ラムダ計算を使用してソリューションを表します。2つの完全に異なるもの。
バイナリウォーリアー

4
申し訳ありませんが、「手続き型プログラミング」というフレーズは、以前に思いついたことを頑なに拒否しました。私にとっての「関数分解」は、関数型プログラミングよりも手続き型プログラミングをはるかに示しています。
バイナリウォーリアー

はい、あなたが正しい。関数型プログラミングは、同じ単純なデータ構造(リスト、ツリー、マップ)で繰り返し動作する再利用可能な関数を好むと仮定し、実際にはこれがオブジェクト指向のセールスポイントであると主張しています。Stuart Halloway(Clojure FPの提唱者)を参照してください。「データ型の過剰指定」は「慣用的なOOスタイルの負の結果」であり、AddressBookを他のリッチなOOオブジェクト(非-vectorish&non-maplike)プロパティとメソッド。
ダン

スチュアートHallowayが引用のリンク:thinkrelevance.com/blog/2009/08/12/...
ダン・

2
@danそれは動的に型付けされた言語Clojureで行われる方法かもしれません(私は知らない、私はClojureを使用しない)が、それから結論を出すことは危険だと思う、それはそれが一般的にFPで行われる方法だと思う たとえば、Haskellの人々は、抽象型と情報の隠蔽が非常に大きいようです(Javaの人々ほどではないかもしれませんが)。
sepp2k

7

関数型プログラミングは、複雑さを管理するのに非常に役立ちます。ただし、複雑さは別の方法で考える傾向があり、複雑さをOOPの意味でのカプセル化ではなく、さまざまなレベルで不変データに作用する関数として定義します。

たとえば、最近Clojureでゲームを作成し、ゲームの状態全体を単一の不変のデータ構造で定義しました。

(def starting-game-state {:map ....
                          :player ....
                          :weather ....
                          :other-stuff ....}

また、ゲームのメインループは、ループ内のゲームの状態にいくつかの純粋な関数を適用することで定義できます。

 (loop [initial-state starting-game-state]
   (let [user-input (get-user-input)
         game-state (update-game initial-state user-input)]
     (draw-screen game-state)
     (if-not (game-ended? game-state) (recur game-state))))

呼び出される主要な関数はでupdate-game、これは以前のゲーム状態とユーザー入力を指定してシミュレーションステップを実行し、新しいゲーム状態を返します。

では、複雑さはどこにあるのでしょうか?私の見解では、それは非常にうまく管理されています。

  • 確かに、ゲームの更新機能は多くの作業を行いますが、それ自体は他の機能を構成することによって構築されるため、実際には非常に単純です。いくつかレベルを下げても、関数はまだ非常に単純で、「マップタイルにオブジェクトを追加する」などの操作を行います。
  • 確かに、ゲームの状態はビッグデータ構造です。ただし、これも下位レベルのデータ構造を構成することで構築されただけです。また、メソッドが埋め込まれているのではなく「純粋なデータ」であり、クラス定義が必要なため(必要に応じて、非常に効率的な不変のJSONオブジェクトと考えることができます)、ボイラープレートはほとんどありません。

OOPはカプセル化によって複雑さを管理することもできますが、これをOOPと比較すると、機能にはいくつかの非常に大きな利点があります。

  • ゲーム状態データ構造は不変であるため、多くの処理を簡単に並行して実行できます。たとえば、ゲームロジックとは異なるスレッドで描画画面を呼び出すレンダリングを行うことは完全に安全です。互いに影響を与えたり、一貫性のない状態を確認したりすることはできません。大きな可変オブジェクトグラフでは、これは驚くほど難しい......
  • ゲームの状態のスナップショットはいつでも取得できます。リプレイは簡単です(Clojureの永続的なデータ構造のおかげで、ほとんどのデータが共有されているため、コピーはほとんどメモリを占有しません)。また、更新ゲームを実行して「未来を予測」し、AIがさまざまな動きを評価できるようにすることもできます。
  • 厳格なクラス階層を定義するなど、OOPパラダイムに適合するために難しいトレードオフを行う必要はありませんでした。この意味で、機能データ構造は、柔軟なプロトタイプベースのシステムのように動作します。

最後に、関数型言語とOOP言語の複雑さを管理する方法についてより多くの洞察に興味がある人のために、Rich Hickeyの基調講演Simple Made Easyのビデオを再編集します(Strange Loopテクノロジー会議で撮影)


2
ゲームは、強制不変性の想定される「メリット」を示す最悪の例の1つだと思います。ゲーム内では常に物事が動き回っているため、常にゲームの状態を再構築する必要があります。そして、すべてが不変である場合、ゲームの状態を再構築するだけでなく、それへの参照を保持する、またはその参照を保持するグラフ内のすべてを、全体をリサイクルするまで再帰的に繰り返す必要があることを意味します30を超えるFPSでプログラムし、大量のGCを起動します!あなたはそれの外に良好なパフォーマンスを得る方法は...ありません
メイソンウィーラー

7
もちろん、ゲームは不変性があり難しいです-だから私はそれがまだ機能することを示すためにそれを選んだのです!ただし、永続的なデータ構造ができることには驚かれることでしょう。ゲームの状態のほとんどは再構築する必要はなく、変化するものだけです。確かにオーバーヘッドがいくらかありますが、それは小さな一定の要因にすぎません。.....私に十分なコアを与え、私はあなたのシングルスレッドのC ++ゲームエンジンを打つだろう
mikera

3
@Mason Wheeler:実際には、GCをほとんど使わずに、不変オブジェクトで実質的に同等の(突然変異と同等の)パフォーマンスを得ることできます。Clojureの秘trickは、永続的なデータ構造を使用することです。これらはプログラマーにとって不変ですが、実際には内部で変更可能です。両方の長所。
ジョナスプラッカ

4
@quant_devより多くのコアは、より良いコア...より安いescapistmagazine.com/news/view/...
deworde

6
@quant_dev-それは言い訳ではなく、コアの数でパフォーマンスをほぼ線形にスケーリングすることでそれを補うことができれば、一定のオーバーヘッドが発生する方が良いという数学的およびアーキテクチャ上の事実です。関数型言語が最終的に優れたパフォーマンスを提供する理由は、シングルコアパフォーマンスのラインの終わりに来ており、それは将来の並行性と並列性に関するものだからです。このアプローチを機能させるには、機能的なアプローチ(特に不変性)が重要です。
ミケラ

3

「オブジェクト指向プログラミングは、アルゴリズムとデータに同時に適用される抽象化のレベルを提供します。これは、機能分解だけでは提供されなかった一種の抽象化です。」

機能分解だけでは、アルゴリズムやプログラムを作成するには不十分です。データも表現する必要があります。上記のステートメントは、機能的なケースの「データ」が最も初歩的な種類であると暗黙的に仮定している(または少なくとも理解できるようになっている)と考えています。そのような言語でのプログラミングは明らかにあまり便利ではありません。ただし、Clojureなどの多くの、特に新しくて現代的な機能(またはマルチパラダイム)言語は、リストだけでなく、文字列、ベクター、マップとセット、レコード、構造体、オブジェクトなどの豊富なデータ構造を提供します!-メタデータとポリモーフィズム。

オブジェクト指向の抽象化の大きな実用的な成功は、ほとんど議論の余地がありません。しかし、それは最後の言葉ですか?あなたが書いたように、並行性の問題はすでに大きな痛みであり、古典的なオブジェクト指向には並行性の考えがまったくありません。その結果、同時実行性を処理するための事実上のオブジェクト指向ソリューションは単にダクトテープを重ね合わせただけです:動作しますが、簡単に台無しになり、手元の重要なタスクからかなりの量の脳資源を奪い、うまくスケールしません。たぶん、多くの世界のベストをとることが可能です。それが現代のマルチパラダイム言語が追求していることです。


1
「大規模なオブジェクト指向、小規模なオブジェクト指向」というフレーズをどこかで聞いたことがあります。マイケル・フェザーズがそれを引用したと思います。つまり、FPは大きなプログラムの特定の部分に適している可能性がありますが、一般的にはオブジェクト指向であるべきです。
ダン

また、すべてにClojureを使用する代わりに、より伝統的なOO構文でより明確に表現されているものでさえ、データ処理ビットにClojureを使用し、それがよりきれいな場合、Javaまたは他のOO言語を他のビットに使用してみてください。プログラムのすべての部分に同じ言語を使用したマルチパラダイムプログラミングではなく、ポリグロットプログラミング。(ほとんどのWebアプリケーションが異なるレイヤーにSQLとOOを使用する方法のようなものです。)?
ダン

@ダン:仕事に最適なツールを使用してください。多言語プログラミングでは、重要な要素は言語間の便利な通信であり、ClojureとJavaが一緒にうまく機能することはほとんどありませんでした。Clojureのほとんどのプログラムは、あちこちでJDKの標準Javaライブラリの少なくとも一部を使用していると思います。
ジョナスプラッカ

2

可変状態は、プログラミングとソフトウェア/システム設計に関連するほとんどの複雑さと問題の根源です。

OOは可変状態を採用しています。FPは可変状態を嫌います。

OOとFPの両方に用途とスイートスポットがあります。賢明に選択してください。「クロージャーは貧乏人のオブジェクトです。オブジェクトは貧乏人の閉鎖です。」という格言を思い出してください。


3
あなたの冒頭の主張が真実かどうかはわかりません。「ほとんど」の複雑さの根源?私が行ったり見たりしたプログラミングでは、問題はコードの抽象化の欠如や詳細の過剰なほど可変性のある状態ではありません。
ダン

1
@ダン:興味深い。実際、私は多くの反対を見てきました。問題は抽象化の過剰使用に起因し、実際に起こっていることの詳細を理解し、必要に応じて修正することを困難にします。
メイソンウィーラー

1

関数型プログラミングはオブジェクトを持つことができますが、それらのオブジェクトは不変である傾向があります。純粋な関数(副作用のない関数)は、それらのデータ構造で動作します。オブジェクト指向プログラミング言語で不変オブジェクトを作成することは可能ですが、それを行うように設計されていなかったため、使用される傾向がありません。これにより、オブジェクト指向プログラムについて推論することが難しくなります。

非常に簡単な例を見てみましょう。OracleがJava Stringsにリバースメソッドを持たせることを決定し、次のコードを記述したとしましょう。

String x = "abc";
StringBuffer y = new StringBuffer(x);
y.reverse();
x.reverse();
x.toString().equals(y.toString());

最後の行は何に評価されますか?これがfalseと評価されることを知るには、Stringクラスの特別な知識が必要です。

独自のクラスWuHoStringを作成した場合

String x = "abc";
WuHoString y = new WuHoString(x);
y.reverse();
x.reverse();
x.toString().equals(y.toString())

最後の行がどのように評価されるかを知ることは不可能です。

関数型プログラミングスタイルでは、次のように記述されます。

String x;
equals(toString(reverse(x)), toString(reverse(WuHoString(x))))

そしてそれは真実であるべきです。

最も基本的なクラスの1つの関数の推論が非常に困難な場合、この可変オブジェクトの概念を導入することで複雑さが増したか減ったかどうか疑問に思います。

明らかに、オブジェクト指向を構成するもの、機能的であることの意味、および両方を持つことの意味についてのあらゆる種類の定義があります。私にとっては、ファーストクラスの関数のようなものは持っていないが、他の言語はそれのために作られている言語で「関数型プログラミングスタイル」を持つことができます。


3
オブジェクト指向言語は不変オブジェクト用に構築されておらず、後で文字列(Javaを含むほとんどのオブジェクト指向言語では不変)を使用する例を使用すると言うのは少しおかしいです。また、不変オブジェクト(たとえば、Scala)に重点を置いて設計されたオブジェクト指向(またはマルチパラダイム)言語があることを指摘する必要があります。
sepp2k

@ sepp2k:慣れてください。FPの支持者は、現実世界のコーディングとは関係のない、奇妙で不自然な例を常に投げかけています。強制不変性などのコアFPコンセプトを適切に見せるための唯一の方法です。
メイソンウィーラー

1
@メイソン:え?「Java(およびC#、pythonなど)が不変の文字列を使用し、うまく機能する」と言うことは、不変性を良くするための最良の方法ではないでしょうか?
sepp2k

1
@ sepp2k:不変の文字列が非常にうまく機能する場合、なぜStringBuilder / StringBufferスタイルのクラスがずっと表示され続けるのですか?それはあなたの邪魔をする抽象化の反転のもう一つの例です。
メイソンウィーラー

2
多くのオブジェクト指向言語では、不変オブジェクトを作成できます。しかし、メソッドをクラスに結び付けるという概念は、私の観点からは本当に落胆させます。文字列の例は、実際には不自然な例ではありません。javaでメソッドを呼び出すたびに、その関数内でパラメーターが変更されるかどうかを判断します。
WuHoUnited

0

ほとんどの場合、古典的なOOP抽象化では同時実行の複雑さはカバーされないと思います。したがって、OOPは(本来の意味では)FPを除外しません。そのため、scalaのようなものが表示されます。


0

答えは言語によって異なります。たとえば、Lispには、コードデータであるという本当にきちんとしたものがあります。あなたが書くアルゴリズムは、実際には単なるLispリストです!プログラムを作成するのと同じ方法でデータを保存します。この抽象化は、OOPよりも簡単かつ徹底的であり、いくつかの本当にすてきなことを実行できます(マクロをチェックアウトします)。

Haskell(および私が想像する同様の言語)には、完全に異なる答えがあります:代数的データ型。代数データ型はC構造体に似ていますが、より多くのオプションがあります。これらのデータ型は、データのモデル化に必要な抽象化を提供します。関数は、アルゴリズムのモデル化に必要な抽象化を提供します。型クラスおよびその他の高度な機能は、両方に対してさらに高いレベルの抽象化を提供します。

たとえば、楽しみのためにTPLと呼ばれるプログラミング言語に取り組んでいます。代数的データ型は、それが作る本当に簡単な値を表すために:

data TPLValue = Null
              | Number Integer
              | String String
              | List [TPLValue]
              | Function [TPLValue] TPLValue
              -- There's more in the real code...

これが何を言う-非常に視覚的な方法では- TPLValue(私の言語の任意の値)ができることであるNullNumberとのInteger値、あるいはFunction値のリスト(パラメータ)と最終値(ボディを持ちます)。

次に、型クラスを使用して、一般的な動作をエンコードできます。例えば、私が作ることができるTPLValueのとインスタンスShow、それは文字列に変換できることを意味しています。

さらに、特定の型(自分で実装しなかった型を含む)の動作を指定する必要がある場合は、独自の型クラスを使用できます。たとえば、適切な通常の値を取得して返すExtractable関数を作成できる型クラスがありますTPLValue。こうしてextract変換することができるNumberIntegerまたはStringString限りようにIntegerStringのインスタンスですExtractable

最後に、私のプログラムのメインロジックは、evalやなどのいくつかの関数にありapplyます。これらは本当にコアです-それらはTPLValues を取り、それらをさらにTPLValuesに変換し、状態とエラーを処理します。

全体として、Haskellコードで使用している抽象化は、実際にはOOP言語で使用したものよりも強力です。


ええ、愛を得なければなりませんeval。「ねえ、私を見てください。私は自分のセキュリティホールを書く必要はありません。プログラミング言語に組み込まれた任意のコード実行の脆弱性があります!」データをコードと統合することが、これまでで最も一般的なセキュリティ脆弱性の2つのクラスの1つの根本原因です。SQLインジェクション攻撃(他の多くのことで)によって誰かがハッキングされるのを見るのは、プログラマーがコードからデータを適切に分離する方法を知らないためです。
メイソンウィーラー

evalLispの構造にあまり依存しませんeval。JavaScriptやPythonなどの言語で使用できます。本当の力はマクロの作成にあります。マクロは基本的に、データのようなプログラムに作用して他のプログラムを出力するプログラムです。これにより、言語は非常に柔軟になり、強力な抽象化を簡単に作成できます。
ティコンジェルビス

3
はい、「マクロは素晴らしい」という話を何度も聞いたことがあります。しかし、1)実用的であり、実際のコードで実際に行いたいこと、2)関数をサポートする言語では簡単に達成できないことを行うLispマクロの実際の例を見たことはありません。
メイソンウィーラー

1
@MasonWheelerショートサーキットand。ショートサーキットorletlet-recconddefn。これらのいずれも、適用可能な順序言語の関数では実装できません。 for(リスト内包表記)。 dotimesdoto

1
@MattFenwick:OK、上記の2つに3つ目のポイントを追加する必要があります。3)健全なプログラミング言語にまだ組み込まれていません それは私がこれまでに見た唯一の本当に便利なマクロの例であり、あなたが「ねえ、私を見て、私の言語は非常に柔軟なので、私自身の短絡を実装できるand!」「ちょっと私を見てください。私の言語はとても不自由なので、短絡することさえないのでandすべてのために車輪を再発明しなければなりません!」
メイソンウィーラー

0

私が見る限り、引用された文はもはや妥当性を持ちません。

現代のオブジェクト指向言語は、種類が*ではない型を抽象化できません。つまり、より高い種類の型は不明です。それらの型システムは、「Int要素を持つコンテナ、つまり要素に関数をマッピングできるコンテナ」という概念を表現できません。

したがって、Haskellsのようなこの基本関数

fmap :: Functor f => (a -> b) -> f a -> f b 

Java *で簡単に書くことはできません)、たとえば、少なくとも型安全な方法ではありません。したがって、基本的な機能を取得するには、多くの定型文を作成する必要があります。

  1. リストの要素に単純な関数を適用する方法
  2. 同じ単純な関数を配列の要素に適用する方法
  3. 同じ単純な関数をハッシュの値に適用する方法、
  4. ....セット
  5. .... 木
  6. ... 10.同じための単体テスト

それでも、これらの5つのメソッドは基本的に同じコードであり、いくつかの方法があります。対照的に、Haskellでは、次のものが必要です。

  1. リスト、配列、マップ、セット、ツリーのFunctorインスタンス(ほとんどが事前に定義されているか、コンパイラーによって自動的に派生できます)
  2. シンプルな機能

これはJava 8では変更されないことに注意してください(関数をより簡単に適用できますが、正確に上記の問題が発生します。高次関数さえない限り、ほとんどの場合、より高い種類の種類が何に適しているかを理解できます。)

Ceylonのような新しいオブジェクト指向言語でさえ、より高い種類の種類はありません。(私は最近ギャビン・キングに尋ねました、そして、彼は私に言った、それは現時点では重要ではありませんでした。)しかし、コトリンについて知りません。

*)公平を期すために、メソッドfmapを持つインターフェイスFunctorを持つことができます。悪いことは、あなたが言うことはできません:ねえ、私はライブラリクラスSuperConcurrentBlockedDoublyLinkedDequeHasMap、fearコンパイラにfmapを実装する方法を知っています。


FTR:Ceylon タイプチェッカーおよびJavaScriptバックエンドはより高度な型(およびより高いランク型)もサポートするようになりました。これは「実験的」機能と見なされます。しかし、私たちのコミュニティはこの機能の実用的なアプリケーションを見つけるのに苦労しているので、これが言語の「公式」な部分になるかどうかは未解決の問題です。私はない、それはいくつかの段階でのJavaのバックエンドでサポートされていることを期待しています。
ギャビンキング

-2

dBaseでプログラミングしたことがある人なら誰でも、単一行マクロが再利用可能なコードを作成するのにどれほど役立つか知っているでしょう。私はLispでプログラミングしたことはありませんが、コンパイル時マクロを誓う他の多くの人から読みました。コンパイル時にコードをコードに挿入するという考え方は、すべてのCプログラムで「include」ディレクティブを使用して単純な形式で使用されます。LispはLispプログラムでこれを行うことができ、Lispは非常に反射的であるため、より柔軟なインクルードが得られます。

Webから任意のテキスト文字列を取得してデータベースに渡すプログラマーは、プログラマーではありません。同様に、「ユーザー」データが自動的に実行可能コードになることを許可する人は誰でも、明らかに愚かです。これは、プログラムが実行時にデータを操作し、それをコードとして実行できるようにすることが悪い考えであることを意味しません。私は、この技術が将来不可欠であり、実際にほとんどのプログラムを作成する「スマート」コードを持つと信じています。「データ/コードの問題」全体かどうかは、言語のセキュリティの問題です。

ほとんどの言語の問題の1つは、1人のオフラインの人が自分でいくつかの機能を実行するために作成されたということです。現実世界のプログラムでは、多くの人が複数のコアと複数のコンピュータークラスターから常に同時にアクセスできる必要があります。セキュリティはオペレーティングシステムではなく言語の一部である必要があり、そう遠くない将来になります。


2
プログラマーへようこそ。回答のレトリックを引き締め、外部参照を使用して主張の一部をバックアップすることを検討してください。

1
ユーザーデータが自動的に実行可能コードになることを許可するプログラマーは、明らかに無知です。バカじゃない そのようにするのは簡単で明白な場合が多く、彼らがそれが悪い考えであり、より良い解決策が存在する理由がわからない場合、それを行うことを彼らに責めることはできません。(より良い方法があると教えられた後にそうし続けている人は、しかし、明らかに愚かです。)
メイソンウィーラー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.