Does the SML (Poly) CL-like REPL?

Here is a quote from Ron Garrett "Lisping in JPL":

"Debugging a $ 100 million hardware-based program that spans 100 million miles is an interesting experience. Having a read-e-print program running on a spacecraft proved invaluable in finding and fixing the problem."

As a beginner trying to decide where to jump, I tend to ML, because the former professor was raving, and I find many books that combine Lambda Calculus discussions with ML and ML, looks pretty reasonable. (I will eventually learn this.)

So, does ML REPL have where, for example, Lisp, you can just “add more code” when it works, i.e. Can Mr. Garrett $ 100 Million Hardware Work On ML?

+4
source share
2 answers

Poly / ML starts with REPL by default, which is similar to SML / NJ. Moreover, you can easily call the compiler at runtime: it will generate its own code for you and add it to the ML environment as an eval in LISP, but it is statically typed and really is machine code, not one interpreted.

The PolyML.Compiler structure provides various (relatively stable) interfaces for this, in addition to the official SML standard.

Here is an example for Poly / ML 5.5 or 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; 

Now we can call this in a regular Poly / ML REPL as follows:

 > eval "1 + 1"; val it = 2: int val it = (): unit > eval "fun f 0 = 1 | fn = 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 

This gives you LISP phased meta programming in the statically typed world of SML.

Note that the PolyML.Compiler structure has additional parameters for controlling the behavior of the compiler call at runtime. Better ask about it on the polyml mailing list.

+5
source

PolyML has a REPL. I don’t know its details, but if it looks like SML / NJ, you cannot use it to crack a running program when it starts. If you want to do this, Common Lisp or Squeak are your best bet. Most other groups of programming languages ​​understand the idea of ​​updating a live program because it works as bad (or at least too dangerous -to-have-available-by-default).

But learn the standard ML. In my opinion, this is a canonical functional language. understanding this makes it easy to understand why functional programming is powerful, and also helps to understand the full range of functional programming languages ​​by their deviations from it.

+2
source

Source: https://habr.com/ru/post/1399651/


All Articles