web-dev-qa-db-ja.com

「実行中」のプログラムの編集?どうして?

私は最近LISPとLispy言語にもっと興味を持っており、それらは非常に強力だと感じています。

私がネット全体で読んでいることの1つは、LISPやClojureなどで書くことの利点は、「実行中に」プログラムを編集できることです。

何かが足りないのかもしれませんが、ポイントは何ですか?

確かに、それは数秒節約できるかもしれませんが、それだけですか?プログラムに変更を加えるときはいつでも、プログラムを停止してから再開するだけで、何十年もの間正常に機能しています。

単に時間を節約する以外の理由があるに違いありません-それは何ですか?

誰かが私にこの機能に夢中になる良いケーススタディを教えてもらえますか? :)

よだれを垂らすのを楽しみにしています!

64
MikeC8

非常にクールなユースケースがいくつかあります。 1つの例はGUIプログラミングです-Emacsの横で実行されているGUIアプリをリアルタイムで開発しているときにこれを見ました:新しいボタンのコードを追加し、「Cc Cc」を押してその単一の関数をコンパイルし、ボタンだけウィンドウに表示!アプリを閉じて再度開く必要はありませんでした。次に、ウィジェットの調整とレイアウトの操作を開始すると、開いているウィンドウが即座に再配置されます。ボタンが移動したり、新しいテキストフィールドが表示されたりするなど、小さな変更を加えるたびに実行されます。

もう1つの例は、プログラマーが3Dテトリスゲームをリアルタイムで作成するClojureOpenGLライブラリ「Penumbra」に関する優れたスクリーンキャストです。彼は、emacsの横にある空のOpenGLウィンドウから始めます。彼はキューブオブジェクト(C-M-x)を定義し、それが画面上にあります。コマンドを実行して回転させ、すぐに回転を開始します。異なる場所にさらに5つのキューブを定義するループを実行し、それらが表示されるpop-pop-pop-pop-pop。それはすべてすぐに反応し、完全なOpenGLツールキットで遊ぶことができます。立方体に新しい表面テクスチャを追加して、すぐに表示されることを確認してください。それは順応性のある3Dワールドになります。コードは、変更のたびに3Dキャンバスを閉じて再度開くのではなく、既存のワールドを動的に変更します。

Penumbra Livecoding Screencast -最高のエクスペリエンスのためにHDバージョンをダウンロードします。

Clojureのオーディオライブラリ「Overtone」に関するすばらしいプレゼンテーション/スクリーンキャストもあります。ライブラリは、音波を操作するための一連のシンセ関数を備えたシンセサイザーツールキットです。プレゼンテーション中に、開発者はトーンの再生を開始するコードを少し記述します。次に、彼は10秒間、そのサウンドを10回再生するが、毎回周波数を高くするループを作成します。C-M-xを聞くと、音が高くなります。リアルタイムで20分のスペースを超えて、彼は歌を歌い始めます。それはとても楽しいように見えます。

倍音プレゼンテーションリンク

その他の用途は、たとえば次のとおりです。Webクロール/データマイニング-情報をリアルタイムで抽出するためのアルゴリズムを開発および改良し、各ステップで返されるデータを確認します。ロボット工学プログラミング-ロボットが生きている間にコマンドをロボットに送信します。顔/画像の認識-OpenCVのようなライブラリを使用すると、コードを開発しているときに、ライブラリが画像/ビデオで認識するものを変更内容が即座に更新します。数学の仕事(Clojureには統計用の「Incanter」があります)。変更が作業中のデータにどのような影響を与えたかをすぐに確認したい環境。

これが、REPLを目の前に置くことの最も楽しい側面です。具体的で、順応性がなく、インタラクティブでなかったものが始まります。GUIデザイン、3Dグラフィックス、プログラムによるサウンド制作、抽出データの変換では、これらのことは通常、独立企業間で行われていますが、Clojure(およびある程度他の動的言語でも)を使用すると、実際に具体的かつ即時に作成されます。コードを記述するとすぐに、それぞれの変更が表示されます。何かが機能しない場合、または期待した結果が得られない場合は、見逃したものを変更して、すぐに再実行します。

Clojureはこれを行うことに非常に連携しています。ワイルドなことは、Javaライブラリを同じ方法でリアルタイムで使用できることです-Java自体は使用できないという事実にもかかわらず!したがって、OvertoneはJava Javaでは不可能だったにもかかわらず、リアルタイムのシンセライブラリ、PenumbraはJava OpenGLバインディングなどを使用しています。これは、RichHickeyがClojureを設計したためです。その場でJVMバイトコードにコンパイルできます。これは素晴らしい言語です。Clojureは、プログラミングが非常に楽しく生産的になることに多大な貢献をしてきました。

56
Jeremy Rayman

単に時間を節約する以外の理由があるに違いありません-それは何ですか?

いいえ、ありません。つまり、決しては次のとおりです:理由全体コンピュータを使用することは時間を節約することです。手でできないことは、コンピューターでできることではありません。少し時間がかかります。

この場合、「数秒」を却下することはありません。これは、プログラミングのキャリア全体で、一日中何よりも頻繁に行うことの1つだからです。再コンパイルに数秒、再実行に数秒、プログラムが前回の状態を再現するのに数秒-高速のワークステーションでも、反復の間隔は簡単に1分になります。 (以前ははるかに悪化していましたが、ハードウェアの高速化により、ひどくなく、良くありませんでした。ファイル全体または最悪の再コンパイルはI/Oバウンドであり、より詳細なコンパイルの速度に匹敵することはありません*。)

LISPでは、すでに実行中のプロセスで単一の関数を再コンパイルするのはほぼ瞬時であり(5年前のラップトップでも、0.1秒も見たことがありません)、再起動すると、状態を再作成する必要がなくなります。 、何かが合図したときでさえ。

これは、私がプログラマーとして行う最も遅くて最も一般的なことの1つを100倍以上高速化するツールです。他に何が必要かわかりません。私たちはおそらくいくつかの理由を補うことができますが、これが十分な理由ではない場合、私は何が起こるかわかりません。ええと、それもかなりクールですか? :-)

(*誰かがテクノロジーに関係することについて「決して」と言うときはいつでも、その人は常に2年後に完全なモロンのように見えてしまいます。LISPの寿命にもかかわらず、私は例外ではありません。)

57
Ken

LISPにはマーケティングスローガンがあります。

LISPとその増分開発方法では、ソフトウェアシステムへの変更のコストは、ソフトウェア全体のサイズではなく、変更のサイズに依存します。

大規模なソフトウェアシステムを使用している場合でも、変更のコスト(時間、...)は変更のサイズに比例します。新しいメソッドを追加したり、新しいメソッドを変更したりした場合、メソッドを編集し、メソッドをインクリメンタルにコンパイルし、メソッドをインクリメンタルにロードする作業に関連して作業が残ります。

多くの従来のソフトウェア環境では、メソッドの変更には、部分的な再コンパイル、新しいリンクされた実行可能ファイル、再起動、リロードなどが必要になる場合があります。ソフトウェアが大きいほど、時間がかかります。

人間の場合、これはおそらくフローの状態から抜け出すことを意味します。これは、優れたLISP環境の生産性の一部です。プログラマーが快適に感じてこのフロー状態に入ると、ソフトウェアシステムに短時間で多くの変更を加えることができます。多くの人がこれを経験していると思います。システムの前に座って応答がなく、待機時間に直面するのとは対照的に、作業は短時間で完了します。

また、私たちと私たちが取り組んでいるプログラムとの間には、ほとんど認知距離がありません。たとえば、バッチ環境でクラスを編集する場合、変更による影響を想像する必要があります。 LISPでは、クラスを編集し、同時にオブジェクト自体を変更します。つまり、オブジェクトの動作を直接変更します。バッチの編集-コンパイル-リンク-実行-テストのサイクルの後、オブジェクトの新しいバージョンではありません。

LISPシステムでは、CADシステムのクラスを変更すると、すぐにアクティブにできます。LISPが大規模なソフトウェアチームで機能するかどうかを尋ねられた場合、答えは大規模なソフトウェアである可能性があります。インクリメンタルに取り組む場合、チームは必要ありません。問題は、インクリメンタル開発に精通した本当に優秀なソフトウェア開発者がまれであったことです。

多くのアプリケーションでは、別個のスクリプト言語レイヤーがあり、元の開発者向け(ユーザー向けではない場合もあります)です。 LISPではこれは必要ありませんLISPはそれ自身の拡張言語です

27
Rainer Joswig

NASAの誰かが彼の経験を説明したのを覚えています。彼のチームは、70年代に宇宙船で使用されていたソフトを実装しました。そして、いくつかのバグが見つかったとき、彼らはその場でソフトをリモートで効果的に変更しました。

または、実行に数日かかる長いプロセスがあり、最後にアクセス許可やその他の小さな問題のために結果を書き込めないことを想像してみてください。

さらに別の例。あなたは統合段階にあり、多くの小さな変更を加える必要があります。そして再びそれらの多く。 Javaでこのような可能性を夢見ています。現在、アプリケーションを再構築して再インストールするのに30〜40分かかるからです(10分で再構築するため)。

14
Oleg Pavliv

Erlangのようなものを見る場合、ポイントはダウンタイムを回避することです。

それはあなたがほんの数秒間オフにすることができない電話スイッチのようなもので動作します。

より通常の使用法では、これは「あると便利」な機能ですが、おそらく重要ではありません。

9
David N. Welton

実際のデータが表示されます。それは大きな利点です。そうすれば、推測する必要はありません。

5
Flinkman

できるから?

真剣に、しばらく試してみると、REPLなしで古いプログラミング言語に戻ると痛みを感じるでしょう。

インスタントフィードバック、テストフィクスチャで偽のプログラム状態を設定することなく簡単に迅速なテストを行うことができます。実行中のプログラムの状態を検査する機能(その変数の値は何ですか)。これらはすべてリアルタイムの節約になります。

5
Marko

これは主に開発用であり、時間の節約になります。

しかし、時間の節約は驚くほど重要です。

慣れると、昔の方法に戻ると、飛行機からタールで泳ぐようになります。

産業用システムでは、これはダウンタイムや危険な状態を緩和するためのPLCプログラミングに使用されます。

これらは、原子力発電所、製造システム、製鉄所などで使用されるシステムです。プロセスは常に継続的に実行されており、ダウンタイムは非常に高価であるか安全ではありません。原子炉の冷却を制御しているシステムを想像してみてください。そのシステムをオフにして新しいコードをデプロイすることはできません。実行中にシステムを変更できる必要があります。

これは、電話スイッチシステムのErlangの回答に似ています。

2
earlNameless

さて、あなたがサーバーにパッチを当てる必要があると想像してください、そしてnotそれを止めてください。

これを「典型的な」言語で行うと、かなりの魔法が必要になります。実行中のコードの「背後」を移動する必要があります。アセンブリで関数テーブルなどにパッチを適用し、関数へのポインタを操作する必要があると思います。バグに適した場所です。

LISPでは、ダウンタイムなしで更新するという考えが言語モデルに組み込まれています。回避できない更新の複雑さ(長時間実行される接続をどのように処理するか)がいくつかありますが、コンパイル言語の重い魔法は必要ありません。

私はそれにかなりの時間を費やしていませんが(つまり、有用なものは何もありません)、ダウンタイムなしでネットワーク上で少なくともsomeライブパッチを実行するCommonLISPのサーバーのプロトタイプを作成しました。

1
Paul Nathan

Casey Muratoriは、CおよびMicrosoftのC/C++コンパイラでこれを行う方法についていくつかのレッスンを行いました。実際には非常に単純で、数十行のコードしかありません。ビデオをチェックしてください22/24/25:

https://www.youtube.com/watch?v=WMSBRk5WG58

ゲームデザインの理論的根拠は、定数をより迅速に調整して、目的の感情的なテナーを見つけることができるようにすることです。ゲームの感触、ノンプレイヤーの行動スクリプト、セットピースの照明/雰囲気などは、これから多くの恩恵を受けます。

0
user755921

すべてを再起動せずにその場でプログラムを変更すること以外のもう1つの良い点は(何十年もそれを行ってきたからといって、それが最良のことであるとは限りませんよね?)、プログラムを現在の状態で検査できることです。何が起こっているのかを理解することができます。

0
Mariano Montone