When being exposed with foreign import initGlobal :: Effect Unit, it works. However, if foreign import initGlobal :: Unit, it doesn’t have the expected effect! The Effect monad really makes a difference here.
This is most amazing to me. How the heck purescript compiler/esbuild/etc. know the semantic of this? I can’t tell the difference from generated main.js either.
a Effect is more or less (after compilation) just a something wrapped into a function () { ... something .. } - so the effect hast to be called initGlobal() in order to express the effect - if you import it as Unit and use this it will probably just plug a reference to this function somewhere (maybe there is even a optimizer step that just removes the hole step as it is Unit - don’t know to be honest) but will not call it.
You should be able to see this in the generated code.
It is more complicated than that. For the non-effectful version, let _ = initGlobal did get optimized away in the final bundled main.js; it was totally absent so that was understandable.
Then I went back to compare the Effect String vs. String version, both had the initGlobal present in the final main.js. BUT … you guessed it, one with the desired side effect and one without. It is magic
Can you maybe post the part with the generated code? I’m pretty sure the String one will not be “called” - if you do let _ = initGlobal it should not be put through the bind part where the delayed call should be performed (_ <- initGlobal would do that but this should result in an type error)