web-dev-qa-db-ja.com

このような機能を持たない別の言語にコードを移植する場合、ある言語の機能を無視する必要がありますか?

私は現在、非常に大きなプロジェクトで遊んでいます。単純なスクリプト言語のインタープリター。数週間の計画の後で、私は最善の行動方針はインタプリタの一部をPythonでプロトタイプ化し、そのコードをCに移植することだと判断しました。

最初に、Pythonを使用して、自分が作成したいくつかのEBNFに基づいた簡単なレクサーを作成しました。レクサーは状態を処理する必要があったので、PythonのOOPツールを多用しました。プロトタイプに満足したら、Cに移植することにしました。

もちろん、Pythonはオブジェクト指向であり、クラスがあります。一方、Cにはそのような概念はありません。私は自分のレクサーを書き直すべきかどうか疑問に思い始めます。クラスによる状態の提供に大きく依存していましたが、Cではクラスを使用できませんでした。

そこで、レクサー全体をゼロから書き直して、関数とグローバル変数のみを使用するようにしました。これは少し冗長でデバッグが難しいコードを生成し始めました。私は立ち止まり、自分が正しい電話をしていたのかと思った。 コードを固める予定の言語にそのような機能がないという理由だけで、1つの言語の機能を無視するように強制されるべきですか?

これは簡単なように思えるかもしれませんが、プロトタイプが言語の特定の機能(私のものなど)に大きく依存している場合はどうでしょうか?あなたは本当にそのような機能の欠如を補うために何時間も費やすべきでしょうか?

しかし、反対側も同じように簡単に議論できます。別の言語でのこのような機能の不足を補うために、なぜある言語で一義的で冗長なコードを書かざるを得ないのですか?


@MichealDurrantがリクエストしていたので、Cを使用する理由を説明します。

  • スピードのために
  • ポータビリティ3
  • 学習目的
  • 私は一般的に言語を好みます。
  • Cはプログラミング言語を作成するためのデファクトのようです。 Cでは、数多くの言語が作成されています。
5
Christian Dean

Cおよび類似の言語でコンパイラーおよび関連ツールを作成した経験に基づいて、他に優れた選択肢がある場合は、Cでコンパイラーを作成することを選択しません。そして2016年には、より良い選択肢がたくさんあります。しかし、それはコンパイラーであり、YMMVです。

TL; DRの裏話:

「私たちは小さな効率について忘れるべきです。時間の約97%を言います:
時期尚早の最適化がすべての悪の根源です。」
—ドナルドクヌース

彼は続けて、「しかし、私たちはその重要な3%で機会を逃してはなりません。」あなたがそのような問題でクヌース博士の助言を受け入れると仮定すると(そしてあなたは本当にそうするべきです)、それゆえ重要な質問は:あなたはその3%ですか?

疑わしいようです。 Ccanは、Python、Perl、またはPHPがこれまでにないほど低レベルのコードで実行されます。これは、優れた中レベル言語で、構造化コードを機械語命令にレンダリングするのに優れています。コアコンパイラ、データベース、ミドルウェアを作成する人にとっては、Cは確かな選択です。

私の経験では、Pythonはパフォーマンス重視の作業でも十分な速度を持っています。何百万ものテキストレコードを解析、分析、変換するプログラムを実行します。すべてが「純粋なPython」で記述されている場合、おそらく十分な速度ではありません。しかし、テキストやXMLの解析、データの山の整理など、多くのタスクはほとんどの場合Cで既に処理されています。Pandas、NumPy、LXMLなどのモジュールは、 Pythonはそれらの最適化を利用しますが、非常にクリーンで標準化された高水準言語です。他の場所に行く必要はほとんどありません。 、メインプログラムフローがPythonで管理されている、CまたはCythonでの非常に狭義の最適化は優れています。

長年に渡って大量のC(オペレーティングシステム、コンパイラ、ミドルウェア、アプリケーション、ユーティリティ)をじっくり見ていて、同じものをいくつか書いてきたので、Cは特に移植性があるという考えに異議を唱えました。それが出現した時代と比較されます。しかし、それは1970年代と1980年代でした。競争はほとんど完全にポータブルではありませんでした。 Cは、プラットフォームのバイトオーダー、ワード長、アドレッシングセマンティクス、およびオペレーティングシステムのフレーバー/バージョンの違いに異常にさらされたままです。多くのプラットフォームを実行するためのコードは、しばしば#ifdefおよび直接的なプラットフォームの知識。それは醜いです。結局のところ、Java、Go、Python、JavaScriptなどの最新の言語と比較すると、Cはない非常に移植可能です。

ですから、Cが好きで、それを研究したい、またはそこで働きたいなら、神のご加護を。しかし、すでにお気づきのように、それは現代の基準では特に支援的な環境ではありません。クラス、辞書、柔軟なリスト、優れたシンプルな文字列照合、setCounterなどの問題指向のデータ構造、簡単な例外処理、強力なモジュールサポート...価値のあるもののリストC欠如は非常に長いです。 Cello のようなフレームワークを使用すると、いくつかの上位レベルの機能を取り戻すことができる場合があります。それでも、Cは45年前の最高のデザインです。それは、それ以来出現してきたものよりも、容易さ、柔軟性、堅牢性、および構造における多くの進歩に欠けています。

Cの潜在的に高速な実行速度の利点を、サポートの少ない環境、開発時間の延長、信頼性の低下などの要因と比較検討する必要があります。 1970年か1980年に、システムリソースは非常にタイトだったので、optimize-optimize-optimizeは理にかなっています。スマートフォンでもマルチコアプロセッサとギガバイトメモリの今日の今日では、パフォーマンス以外の属性の最適化を正当に検討できます。市場投入までの時間、プログラムの高度化、信頼性、保守性-Python(または別の高水準言語))で合理的に最適化できるものは多くあり、すぐには最適化できません。 Cで.

7
Jonathan Eunice

このような場合に機能を無視しても意味がありません。

プロトタイピングにPythonを使用する典型的な理由は、機能を使用することで、Cよりも時間と「スペース」(=コードの行)で物事を実装できるためですPythonは持っていますが、Cは持っていません。 C機能と1:1で対応するPython機能のみに制限する場合、Pythonを直接使用しても意味がなくなります。プログラムを最初からC。

ところで、ユースケースとして Cython を検討しましたか?

7
Doc Brown

Turing-Complete言語の機能は、他の任意のTuring-Complete言語で実装できます。そうではなかったとしても、私たちが開発した最初のプログラミング言語にはまだ行き詰っています。だから本当に、それはあなたが費やしたいどのくらいの努力にかかっています。

ある意味で、あなたは間違った質問をしています。 「ソース言語に機能が存在しない場合、ターゲット言語で機能を実装する必要がありますか?」という質問ではありません。 」

つまり、ターゲット言語でオブジェクト指向を正しく実装するために、ソース言語でオブジェクト指向を使用する必要はありません。

Cは言語インタープリターとコンパイラーにとって自然な選択です。比較的単純であるため、実際には他の言語を実装するのに理想的です。なぜなら、パラダイム自体に組み込まれている部分が比較的少ないため、独自の設計の選択に縛られないためです。

さらに、Cは中間言語をコンパイルするのに適したターゲットになります。クロスプラットフォームであるため、結果のコードをほとんどどこでもバイナリにコンパイルできます。

3
Robert Harvey

あなたはあなたのPythonプログラムを書いて、概念を証明するために、私は理解しています-私はそれは完璧に立派で立派だと思います。

あなたの計画は、最初から最終的にimplementをCで作成することでした。同様に、その言語の速度と効果を望んでいます(たとえCとPythonの利点については議論しますが、ここでは重要ではありません)たくさんの人がいます。

しかし、あなたは言う、しかし、あなたはCへの​​概念実証をportingしてきた-私はそれを見るのは一般的に間違った方法だと思う。別の言語での概念実証はportedであってはなりません-実装はゼロからの実装であり、あなたが証明した概念、あなたがそれを行うために使用したプログラムではない-私はあなたが違いを見ることを望みます。 Cでの実装を試みる前に、Pythonの実装を完全に「忘れる」ほうがはるかに良いと思います。

1
tofro

コンパイラのブートストラップは常に困難です。 IBM/370用のModula2コンパイラーを書いたことがあります。コンパイラはModula2で提供されました。それで私は自分の髪の毛で沼から身を引いたミュンヒハウゼン男爵の状況にいた。私がやった方法は、最初にModula2からPascalVSに非常によく似たクロスコンパイラを作成することでした(どちらもWirthの子です)。その後、コンパイラをコンパイルすることができました。結果として、コンパイラーはMコードを生成しました。これは、Modula2コンパイラーに付属するインタープリターで実行できます。 Veeeryは遅いですが、動作しています。したがって、アセンブラーのコードジェネレーターを作成する最後の方法です。

さて、それから何を学ぶことができますか?ロバートの答えを見てください。 Cで直接コンパイラーを作成することは、「スマート」ではないかもしれませんが、多くの作業を節約できます。

1
qwerty_so