Simon Peyton-Jones wrote:
| Yes, it definitely helps. It seems to be equivalent to "P1, but all | foreign exports are bound".
Stupid me -- so it is! Yet you disliked P1 enough to put forward P2. Was the 'main thread' thing the only reason?
... and the protests against extending the FFI syntax. I hadn't thought of just making all foreign exports "bound" before, mostly due to performance concerns... In the beginning, People seemed to be concerned about any performance impact on "normal use", and, perhaps more importantly, I had slightly different plans for the GHC implementation where the cost would have been greater. After spending some time thinking about how to implement P2, I think the cost can be neglected. P2 seems to be a proposal that solves all issues that we are interested in, except for one issue: complexity. Compared to P1, it removes an extra keyword and solves the main-thread issue. P4 makes two small tradeoffs to achieve simplicity: all foreign exports require bound-thread-scheduling (small performance cost), and the main-thread issue has to be addressed by a separate workaround. You've convinced me that the gain in simplicity is worth that.
| *) forkOS needn't be a primitive, it can be implemented via the FFI (cf | Section 3.2, first Proposal).
True, but clumsy; I think it should be in the spec.
OK, then let's just add a remark... OTOH, it seems like it makes the formal semantics more complicated; bound threads now have two distinct ways of ending --- returning to a native thread and returning to nirvana. If we don't model forkOS, then we'd have a rule (END) that says that unbound threads just cease to exist, and a rule (HRET) that says that bound threads return to the native thread they're bound to.
All good points -- would you like to add them to the document?
OK.
We seem to be converging!
Yes! :-)
We might add (3): on MacOS, arrange the GHC runtime so that it spawns a thread to start and run Haskell, and then (in the main thread) calls in to the Haskell export 'mainMacOs'... which will then be guaranteed to be the main thread. Ugly though.
So that we would have one "main" action running in an unbound thread, and a "mainBound" action bound to the main OS thread? Yes that's ugly... (and I'm afraid of the linker tricks that will be necessary to make "mainBound" really optional).
for (1), the main-thread binding could be on MacOS only; and that is equivalent, but much less fragile, to your hack. So perhaps it'd do?
Perhaps a RTS option, which perhaps defaults to "bound" on MacOS and to "unbound" everywhere else, so we can avoid slowing down non-GUI programs on MacOS and so that we can use broken libraries on other platforms, if there are any. Programs that require the main thread to be bound could use a runtime assertion to be sure that wrong settings are noticed immediately; something like main = assert currentThreadBound $ do ... I think I like the RTS option best. Cheers, Wolfgang