5

以下は、Ron Garret の "Lisping at JPL" からの引用です。

「1 億マイル離れた場所にある 1 億ドルのハードウェアで実行されているプログラムをデバッグするのは興味深い経験です。宇宙船で実行されている読み取り - 評価 - 印刷ループは、問題を見つけて修正する上で非常に貴重であることが証明されました。」

どこに飛び込むかを決めようとしている初心者として、私は ML に傾倒しています。なぜなら、以前のプロフが絶賛し、ラムダ計算の議論を ML と統合し、ML がかなり正気に見える多くの本を見つけたからです。(最終的にはこれを教えるつもりです。)

では、ML には、Lisp のように実行中に「コードを追加」できる REPL がありますか? つまり、Garret 氏の $100M のハードウェアが ML で実行されている可能性はありますか?

4

2 に答える 2

7

Poly/ML はデフォルトで REPL で起動します。これは SML/NJ に似ています。さらに、実行時にコンパイラを簡単に呼び出すことができます。コンパイラはネイティブ コードを生成しeval、LISP の場合と同様に ML 環境に追加しますが、それは静的に型付けされた実際のマシン コードであり、解釈されたものではありません。

この構造PolyML.Compilerは、公式の SML 標準を超えて、それを行うためのさまざまな (比較的安定した) インターフェースを提供します。

Poly/ML 5.5 または 5.6 の実際の例を次に示します。

fun eval text =
  let
    fun print s = (TextIO.output (TextIO.stdOut, s); TextIO.flushOut TextIO.stdOut);

    val line = ref 1;
    val in_buffer = ref (String.explode text);
    val out_buffer = ref ([]: string list);

    fun output () = String.concat (rev (! out_buffer));

    fun get () =
      (case ! in_buffer of
        [] => NONE
      | c :: cs => (in_buffer := cs; if c = #"\n" then line := ! line + 1 else (); SOME c));
    fun put s = out_buffer := s :: ! out_buffer;
    fun put_message {message = msg1, hard, location = {startLine = line, ...}, context} =
     (put (if hard then "Error: " else "Warning: ");
      PolyML.prettyPrint (put, 76) msg1;
      (case context of NONE => () | SOME msg2 => PolyML.prettyPrint (put, 76) msg2);
      put ("Line " ^ Int.toString line ^ "\n"));

    val parameters =
     [PolyML.Compiler.CPOutStream put,
      PolyML.Compiler.CPErrorMessageProc put_message,
      PolyML.Compiler.CPLineNo (fn () => ! line)];
    val _ =
      (while not (List.null (! in_buffer)) do
        PolyML.compiler (get, parameters) ())
      handle exn =>
        (put ("Exception- " ^ General.exnMessage exn ^ " raised");
          print (output ()); raise exn);
  in print (output ()) end;

これで、次のように通常の Poly/ML REPL でこれを呼び出すことができます。

> eval "1 + 1";
val it = 2: int
val it = (): unit
> eval "fun f 0 = 1 | f n = n * f (n - 1)";
val f = fn: int -> int
val it = (): unit
> eval "f 42";
val it = 1405006117752879898543142606244511569936384000000000: int
val it = (): unit
> f 42;
val it = 1405006117752879898543142606244511569936384000000000: int

これにより、静的に型付けされた SML の世界で LISP スタイルのメタプログラミングが可能になります。

PolyML.Compiler構造体には、ランタイム コンパイラの呼び出しの動作を制御する追加のオプションがあることに注意してください。それについては、polyml メーリング リストで質問してください。

于 2013-03-01T16:52:51.647 に答える
3

PolyML には REPL があります。詳細はわかりませんが、SML/NJ のようなものであれば、実行中のプログラムを実行中のプログラムにぶつけることはできません。それをしたいのであれば、Common Lisp か Squeak が最善の策です -- 残りのプログラミング言語コミュニティのほとんどは、実行中のプログラムを更新するという考えを悪い (または少なくとも危険すぎる) と見なしています。 -have-available-by-default) アイデア。

ただし、標準 ML を学習してください。私の考えでは、それは正規の関数型言語です。それを理解すると、関数型プログラミングが強力な理由を簡単に理解できるようになります。また、関数型プログラミング言語の全範囲を、関数型プログラミング言語からの逸脱によって理解するのにも役立ちます。

于 2012-03-04T16:09:28.953 に答える