Re: Synchronous Platform.worker

In Sep 2018, @ondrej asked about Synchronous Platform.worker.

The thread is closed, but here is an asynchronous Platform.worker using 0.19 based on @rupert 's excellent response; I hope that this is an acceptable way to pass on this information.

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="UTF-8">
  <title>Main</title>
  <script src="src/main.js"></script>
</head>
<body>
  <script>

  var app = Elm.Main.init({
    flags: "ondrej"
  });

  function greet(name) {
    return new Promise(resolve => {
      var app = Elm.Main.init({
        flags: name
      });

      app.ports.sayHello.subscribe(function(data) {
        resolve(data);
      });
    });
  }

  greet('ondrej')
  .then(
    greeting => {
      console.log(greeting);
    }
  )

  </script>
</body>
</html>
port module Main exposing (main)

import Platform


type alias Flags =
    { greeting : String
    }


type alias Model =
    String


port sayHello : String -> Cmd msg


main : Program String String Never
main =
    Platform.worker
        { init = \flags -> ( "Hello " ++ flags, sayHello <| "Hello " ++ flags )
        , update = \msg model -> ( model, Cmd.none )
        , subscriptions = \model -> Sub.none
        }


init : Flags -> ( Model, Cmd msg )
init flags =
    let
        model =
            flags.greeting ++ " world!"

        _ =
            Debug.log "Init" model
    in
    ( model, Cmd.none )


subscriptions : Model -> Sub msg
subscriptions model =
    Sub.none


update : msg -> Model -> ( Model, Cmd msg )
update msg model =
    case msg of
        _ ->
            ( model, Cmd.none )
1 Like

Thanks for the suggestion but it is not exactly what I was looking for.

The reason I wanted specifically the synchronous version is that it would be nice to just replace some JS functions with Elm functions. But since there is no way to have a synchronous Elm call from JS it is not possible to “just” replace some JS function with Elm function. I’m forced to first make that JS function asynchronous which is a breaking change for most of my code.

If you really, really want to do that, you can do it by compiling the Elm code and processing the result.

It would obviously not work for anything that touches the platform code (Tasks, Cmds, Html, etc) but it should work for regular code.

Could you elaborate a bit more on what do you mean by “processing the result”?

The output of the compiler is readable JS. With each version there is a specific format for this output. This can be used to process this output, for example, adding a specific function or a family of functions to the exports.

Please note that this qualifies as a “hack” solution and I’m not really recommending this, especially because the format is an implementation detail that should not be used BUT, you can do it.

Just look at the output of an elm compilation and use your JS knowledge to try to understand it and understand how an automated tool could help you.

That doesn’t sound like a viable solution to me. The output can be changed with any hotfix and it would be quite some work to reverse engineer the inner working of Elm so I can strip out unnecessary stuff.

This is unfortunately the way I’m not willing to go.

Smart choice. This is why I said “If you really, really want to do that” :wink:

Is there a reason this ability isn’t built into (exposd by) Elm?

It just seems to be a prioritization consequence:
https://www.reddit.com/r/elm/comments/3n8naq/is_it_possible_to_call_an_elm_function_from/cvm9lwe/

2 Likes

See also Project Proposal: Compiler for libraries.

2 Likes

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.