
Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime. I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything? Cheers, Simon

This fits in directly with what I am trying to do for the
haskell-ide-engine, where the intention is to expose ghci via an
asynchronous process with communication via message passing.
A bonus would be to have two separate interfaces, one for REPL interaction
for the user, the other to be able to query properties of the loaded code.
I am currently investigating exposing Behavior and RunTerm from haskeline
to create a message passing backend instead.
Alan
On 17 Nov 2015 12:11 PM, "Simon Marlow"
Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

Hi Simon,
IHaskell https://github.com/gibiansky/IHaskell makes use of
dynCompileExpr to evaluate code provided by the user, so that the result
can be sent to the frontend to be displayed.
I don't think we can make it work without using dynCompileExpr, Andrew
would have more to say about this.
On 17 November 2015 at 16:10, Alan & Kim Zimmerman
This fits in directly with what I am trying to do for the haskell-ide-engine, where the intention is to expose ghci via an asynchronous process with communication via message passing.
A bonus would be to have two separate interfaces, one for REPL interaction for the user, the other to be able to query properties of the loaded code.
I am currently investigating exposing Behavior and RunTerm from haskeline to create a message passing backend instead.
Alan On 17 Nov 2015 12:11 PM, "Simon Marlow"
wrote: Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
-- Regards Sumit Sahrawat

I think there will be ways to do what you want in the context of a remote interpreter, but I'll need to understand more about the way in which you use dynCompileExpr. What do you do with the result of dynCompileExpr? Can you run that code in the context of the interpreter instead? Cheers Simon On 17/11/2015 10:47, Sumit Sahrawat, Maths & Computing, IIT (BHU) wrote:
Hi Simon,
IHaskell https://github.com/gibiansky/IHaskell makes use of dynCompileExpr to evaluate code provided by the user, so that the result can be sent to the frontend to be displayed.
I don't think we can make it work without using dynCompileExpr, Andrew would have more to say about this.
On 17 November 2015 at 16:10, Alan & Kim Zimmerman
mailto:alan.zimm@gmail.com> wrote: This fits in directly with what I am trying to do for the haskell-ide-engine, where the intention is to expose ghci via an asynchronous process with communication via message passing.
A bonus would be to have two separate interfaces, one for REPL interaction for the user, the other to be able to query properties of the loaded code.
I am currently investigating exposing Behavior and RunTerm from haskeline to create a message passing backend instead.
Alan
On 17 Nov 2015 12:11 PM, "Simon Marlow"
mailto:marlowsd@gmail.com> wrote: Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org mailto:ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org mailto:ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
-- Regards
Sumit Sahrawat

So the remote GHCi server I had in mind would be too dumb to support this - it would be at a much lower level, with support for linking object code and bytecode and evaluation only. What you probably want for this is a remote interface to the GHC API, similar to what ide-backend provides. Cheers, Simon On 17/11/2015 10:40, Alan & Kim Zimmerman wrote:
This fits in directly with what I am trying to do for the haskell-ide-engine, where the intention is to expose ghci via an asynchronous process with communication via message passing.
A bonus would be to have two separate interfaces, one for REPL interaction for the user, the other to be able to query properties of the loaded code.
I am currently investigating exposing Behavior and RunTerm from haskeline to create a message passing backend instead.
Alan
On 17 Nov 2015 12:11 PM, "Simon Marlow"
mailto:marlowsd@gmail.com> wrote: Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org mailto:ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

I like this idea, and it overlaps very much with the work that still needs
to be done for GHCJSi. I think that for Template Haskell, the restriction
that everything has to be marshalled via Binary is not too problematic,
although it'd require a bit of care if Richard's pre-proposal to expose
more GHC types to TH ( #11081 ) is to be implemented. In particular, the
API for querying the type environment would have to remain implementable
via message passing, so we can't expose the full TcRn there.
compileExpr / dynCompileExpr seem to get some use, perhaps mostly through
the hint package:
http://packdeps.haskellers.com/reverse/hint
But I think the most common use case is just compiling and running Haskell
expressions, without any specific need for interpreted code. The machinery
behind hint could be reworked to have the GHC API produce a dynamic library
for the compiled expression, which could then be loaded into the current
process with the system linker. Or is there some reason that this approach
would be unusable?
luite
On Tue, Nov 17, 2015 at 10:10 AM Simon Marlow
Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon

CC Daniel Corin, maintainer of hint. On 17/11/2015 11:49, Luite Stegeman wrote:
I like this idea, and it overlaps very much with the work that still needs to be done for GHCJSi. I think that for Template Haskell, the restriction that everything has to be marshalled via Binary is not too problematic, although it'd require a bit of care if Richard's pre-proposal to expose more GHC types to TH ( #11081 ) is to be implemented. In particular, the API for querying the type environment would have to remain implementable via message passing, so we can't expose the full TcRn there.
compileExpr / dynCompileExpr seem to get some use, perhaps mostly through the hint package:
http://packdeps.haskellers.com/reverse/hint
But I think the most common use case is just compiling and running Haskell expressions, without any specific need for interpreted code. The machinery behind hint could be reworked to have the GHC API produce a dynamic library for the compiled expression, which could then be loaded into the current process with the system linker. Or is there some reason that this approach would be unusable?
I don't think that simplifies the problem, we would still be dynamically loading and running code in the current process, which is exactly what we do now. The issue is with interpret :: (MonadInterpreter m, Typeable a) => String -> a -> m a which would need to become interpret :: (MonadInterpreter m, Typeable a, Binary a) => String -> a -> m a or else we have to keep the current single-process mechanism for this use case. Cheers, Simon
luite
On Tue, Nov 17, 2015 at 10:10 AM Simon Marlow
mailto:marlowsd@gmail.com> wrote: Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon

How does this interact with typechecker plugins? I assume they would still happen in GHC's process.
I've also been thinking about designing and implementing a mechanisms where programmers could specify custom pretty-printers for their types, and GHC would use these pretty-printers in error messages. This action would also probably need to be in the same process.
Would either of these ideas be affected? My guess is "no", because we should be able to be selective in what gets farmed out to the second process and what stays locally.
Richard
On Nov 17, 2015, at 5:10 AM, Simon Marlow
Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

Simon,
As Sumit said, we use dynCompileExpr for core functionality of IHaskell. I
am not really sure how the change you are proposing affects that, though.
We use dynCompileExpr in several places for evaluation inside the
interpreter context:
1. Evaluating a Haskell expression in the interpreter context, converting
the result to a ByteString, then using fromDynamic to extract the
bytestring and convert it to a value in the compiled context.
2. Getting a file handle from the interpreter context to the compiled
context; this does not actually use dynCompileExpr because there were some
bugs with dynCompileExpr and so I had to literally copy source from
InteractiveEval to reimplement parts of dynCompileExpr (unrelated: the
issue was that dyncompileexpr imported and then unimported Data.Dynamic,
and this messed with data declarations that had already been created in the
interpreter context)
3. Extracting IO a values from the interpreted context to the compiled
context so that they could be run; this is necessary to get displayed
values from the interpreter back to the compiled code.
I think two of our uses, which are both very central to the way IHaskell
works, would be impacted by requiring a Binary instance (or similar), which
is what I think you are proposing (since we have two uses at least where we
marshall `IO x` values via dynCompileExpr, which cannot be serialized, I
believe.)
I am sure that there are alternative ways to do what we are doing, but they
are probably not simple and would take quite a bit of work.
-- Andrew
On Tue, Nov 17, 2015 at 6:29 AM, Richard Eisenberg
How does this interact with typechecker plugins? I assume they would still happen in GHC's process.
I've also been thinking about designing and implementing a mechanisms where programmers could specify custom pretty-printers for their types, and GHC would use these pretty-printers in error messages. This action would also probably need to be in the same process.
Would either of these ideas be affected? My guess is "no", because we should be able to be selective in what gets farmed out to the second process and what stays locally.
Richard
On Nov 17, 2015, at 5:10 AM, Simon Marlow
wrote: Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

Ok, it seems that (1) is easy to support in a remote GHCi, (2) is not, and (3) I'm not sure about. GHCi itself does something very similar to (3): when we compile a statement it becomes a value of type IO [HValue], that we can evaluate and get back a list of the values that were bound to variables by the statement. In remote GHCi I can support this by having an RPC to evaluate the IO action and the returned HValues are remote references (StablePtrs) to values in the interpreter context. In any case I don't plan to break anything unless we have alternative ways to support everything without major upheaval. In the meantime there will probably be a flag to select remote GHCi, and existing use cases will continue to be supported. Cheers Simon On 17/11/2015 17:11, Andrew Gibiansky wrote:
Simon,
As Sumit said, we use dynCompileExpr for core functionality of IHaskell. I am not really sure how the change you are proposing affects that, though.
We use dynCompileExpr in several places for evaluation inside the interpreter context:
1. Evaluating a Haskell expression in the interpreter context, converting the result to a ByteString, then using fromDynamic to extract the bytestring and convert it to a value in the compiled context. 2. Getting a file handle from the interpreter context to the compiled context; this does not actually use dynCompileExpr because there were some bugs with dynCompileExpr and so I had to literally copy source from InteractiveEval to reimplement parts of dynCompileExpr (unrelated: the issue was that dyncompileexpr imported and then unimported Data.Dynamic, and this messed with data declarations that had already been created in the interpreter context) 3. Extracting IO a values from the interpreted context to the compiled context so that they could be run; this is necessary to get displayed values from the interpreter back to the compiled code.
I think two of our uses, which are both very central to the way IHaskell works, would be impacted by requiring a Binary instance (or similar), which is what I think you are proposing (since we have two uses at least where we marshall `IO x` values via dynCompileExpr, which cannot be serialized, I believe.)
I am sure that there are alternative ways to do what we are doing, but they are probably not simple and would take quite a bit of work.
-- Andrew
On Tue, Nov 17, 2015 at 6:29 AM, Richard Eisenberg
mailto:eir@cis.upenn.edu> wrote: How does this interact with typechecker plugins? I assume they would still happen in GHC's process.
I've also been thinking about designing and implementing a mechanisms where programmers could specify custom pretty-printers for their types, and GHC would use these pretty-printers in error messages. This action would also probably need to be in the same process.
Would either of these ideas be affected? My guess is "no", because we should be able to be selective in what gets farmed out to the second process and what stays locally.
Richard
On Nov 17, 2015, at 5:10 AM, Simon Marlow
mailto:marlowsd@gmail.com> wrote: > Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime. > > I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi > > I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything? > > Cheers, > Simon > _______________________________________________ > ghc-devs mailing list > ghc-devs@haskell.org mailto:ghc-devs@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org mailto:ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

The use-case which I've worked on deals with widget messages. Widgets are
stored inside the kernel, and can recieve signals from user code, frontend
events etc.
To capture messages sent by the user code, the messages are queued in a
TChan inside the interpreter environment. Messages from this TChan are
extracted into the kernel using dynCompileExpr and fromDynamic, and
processed as required.
The user input code is executed in the interpreter context, but we also
need to gather information some more information from the context, which is
why dynCompileExpr is crucial there.
On 17 November 2015 at 19:59, Richard Eisenberg
How does this interact with typechecker plugins? I assume they would still happen in GHC's process.
I've also been thinking about designing and implementing a mechanisms where programmers could specify custom pretty-printers for their types, and GHC would use these pretty-printers in error messages. This action would also probably need to be in the same process.
Would either of these ideas be affected? My guess is "no", because we should be able to be selective in what gets farmed out to the second process and what stays locally.
Richard
On Nov 17, 2015, at 5:10 AM, Simon Marlow
wrote: Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
-- Regards Sumit Sahrawat

I've been thinking of these applications before, in the context of cross
compilers, and of how to deal with these things as dependencies.
Custom error message formatting could be done in the same way as Template
Haskell I think, since there appears to be a reasonably well-defined place
where these are needed, and the cost of marshalling the data does not look
prohibitive for this application. It could run in the Quasi monad (which
would perhaps get some extensions) with type similar to
formatError :: Quasi m => TypeError -> m (Maybe Doc)
(IDE people will argue that errors shouldn't be formatted as Doc, some
structured error message format is needed, we could add that later)
Two questions:
- Which formatters would be loaded by GHC? Would libraries supply
formatters that automatically get loaded by everything that depends on the
package?
- How would GHC decide which formatter(s) to call for a specific error?
As for typechecker (and also core-to-core) plugins:
Am I right in thinking that these can usually be treated as a separate
build tool, where having it in a separate package is not too problematic?
This way, plugins could be loaded from dynamic libraries at startup (or for
platforms where this is problematic, GHC could bootstrap itself by linking
the plugins statically). Plugins would be built for the host platform, so
GHC's package database, which lists packages for the target platform, may
not be relevant at all. Cabal would only need to check whether GHC can
somehow load pluginpackage-x.y.z before proceeding with the build.
I like the idea of extending GHC in various places, but for GHCJS I do need
a somewhat workable story for cross-compilation.
(Of course I could make GHCJS a non-crosscompiler, by compiling the whole
compiler to JS and running everything in a JS runtime; everything would
magically work again, but that's a bit too deep down the rabbit-hole for me
at the time...)
luite
Am I right in thinking that typechecker plugins are a special
On Tue, Nov 17, 2015 at 2:30 PM Richard Eisenberg
How does this interact with typechecker plugins? I assume they would still happen in GHC's process.
I've also been thinking about designing and implementing a mechanisms where programmers could specify custom pretty-printers for their types, and GHC would use these pretty-printers in error messages. This action would also probably need to be in the same process.
Would either of these ideas be affected? My guess is "no", because we should be able to be selective in what gets farmed out to the second process and what stays locally.
Richard
On Nov 17, 2015, at 5:10 AM, Simon Marlow
wrote: Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

I like it. Let me make sure that I've understand this correctly: - While GHC doesn't need to be built with profiling if you want to use profiling in the interpeter, you will need multiple versions of the "server binary" for each way you want to implement. This should be pretty reasonable, because the server binary is a lot smaller than GHC. - It seems that GHC will ship bytecode and object code to the server binary. In this case, the interpeted code and compiled code CAN share data among each other; it is just when you want to share data with GHC that you must implement serialization. (Also, external bytecode format?!) - Many people have commented that their extensions use dynCompileExpr. I think these cases can be accommodated, by making the server binary not a standalone application, but a LIBRARY which can be linked against a custom application (e.g. IHaskell). The messages to be sent should not be the values/file descriptors, but the invocations that are being requested of GHC. Unfortunately, this does seem to imply that most things would have to be rewritten from scratch to not use the ghc-api, but use whatever this new library's interface over the message passing is. Honestly, it seems like the hard part is defining the message-passing protocol, esp. since the GHC API is as overgrown as it is today. Edward Excerpts from Simon Marlow's message of 2015-11-17 02:10:55 -0800:
Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon

On 18/11/2015 00:53, Edward Z. Yang wrote:
I like it.
Let me make sure that I've understand this correctly:
- While GHC doesn't need to be built with profiling if you want to use profiling in the interpeter, you will need multiple versions of the "server binary" for each way you want to implement. This should be pretty reasonable, because the server binary is a lot smaller than GHC.
Yes, exactly.
- It seems that GHC will ship bytecode and object code to the server binary. In this case, the interpeted code and compiled code CAN share data among each other; it is just when you want to share data with GHC that you must implement serialization. (Also, external bytecode format?!)
We need to ship bytecode, but not necessarily object code. The idea is to implement the linker API via an RPC protocol to the server binary. It's pretty straightforward actually, I have a prototype running already. We would only need to ship object code if the server were running on a separate machine, that's something for later (if ever).
- Many people have commented that their extensions use dynCompileExpr. I think these cases can be accommodated, by making the server binary not a standalone application, but a LIBRARY which can be linked against a custom application (e.g. IHaskell). The messages to be sent should not be the values/file descriptors, but the invocations that are being requested of GHC. Unfortunately, this does seem to imply that most things would have to be rewritten from scratch to not use the ghc-api, but use whatever this new library's interface over the message passing is.
Hmm, the thing is that it is *already* a library (the GHC API) and I want to make it a separate process, to decouple the runtime that is running the compiler from the one running the interpreted code.
Honestly, it seems like the hard part is defining the message-passing protocol, esp. since the GHC API is as overgrown as it is today.
What I have in mind is much lower level than the GHC API. Here's what I have so far: data Message a where -- linker API LookupSymbol :: String -> Message (Maybe RemotePtr) LoadDLL :: String -> Message (Maybe String) LoadArchive :: String -> Message () -- error? LoadObj :: String -> Message () -- error? UnloadObj :: String -> Message () -- error? AddLibrarySearchPath :: String -> Message RemotePtr RemoveLibrarySearchPath :: RemotePtr -> Message Bool ResolveObjs :: Message Bool -- creating and evaluating bytecode CreateBCO :: ResolvedBCO -> Message RemoteHValue FreeHValue :: RemoteHValue -> Message () Eval :: RemoteHValue {- IO [a] -} -> Message [RemoteHValue] {- [a] -} this is enough to support basic GHCi operations. Cheers, Simon
Edward
Excerpts from Simon Marlow's message of 2015-11-17 02:10:55 -0800:
Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon

Hi Simon, While this is an interesting proposal, Haskell for Mac strongly relies on running interpreted code in the same process. I’m using ’dynCompileExpr’ as well as ’hscStmtWithLocation’ and some other stuff. This is quite crucial for some of the interactive functionality. Imagine a game where the game engine is in Swift linked into the main application and the game logic is in *interpreted* Haskell code. The engine calls into the Haskell code multiple times per frame of the animation and for all keyboard/mouse/etc input (using StablePtr and ForeignPtr to construct the scene graph across the Swift and Haskell heap). This is an intricate dance (e.g, exceptions in either language don’t play nice across the language boundary and using multi-threading in both worlds adds to the fun), but it allows for a very nice interactive and responsive user experience. I actually also might have a use for the architecture that you are proposing. However, I really would like to keep the ability to, at least, optionally run interpreted code in the same process (without profiling etc). Do you think we could have both? Cheers, Manuel
Simon Marlow
: Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

On 18/11/2015 01:41, Manuel M T Chakravarty wrote:
Hi Simon,
While this is an interesting proposal, Haskell for Mac strongly relies on running interpreted code in the same process. I’m using ’dynCompileExpr’ as well as ’hscStmtWithLocation’ and some other stuff.
Let me say first of all that I'm not going to remove anything, so there's no need to worry. But I'd like to explore exactly what you need, so that we can see whether there's a way to accommodate it with a separate-process implementation. hscStmtWithLocation is part of the core GHCi functionality, it is definitely supported. It has a slightly different signature: hscStmtWithLocation :: HscEnv -> String -- ^ The statement -> String -- ^ The source -> Int -- ^ Starting line -> IO ( Maybe ([Id] , RemoteHValue {- IO [HValue] -} , FixityEnv)) RemoteHValue is a reference to a value in the interpreter's context. These have to be evaluated via an explicit API, rather than just unsafeCoercing HValue as we do now. (this is not strictly speaking part of the GHC API, so a separate but interesting question is: why did you need to use this directly, and what should we add to the GHC API?) I believe that many uses of dynCompileExpr can be changed so that the code using the resulting value is moved into the interpreter's context, and then there's no problem.
This is quite crucial for some of the interactive functionality. Imagine a game where the game engine is in Swift linked into the main application and the game logic is in *interpreted* Haskell code. The engine calls into the Haskell code multiple times per frame of the animation and for all keyboard/mouse/etc input (using StablePtr and ForeignPtr to construct the scene graph across the Swift and Haskell heap).
So my question is, why wouldn't you run the whole game engine in the interpreter's context? That's what would happen if you were to load the program into GHCi and run it. Directly calling back and forth between the client of the GHC API and the program being interpreted is arguably a strange thing to do, and it's kind of accidental that we allow it.
I actually also might have a use for the architecture that you are proposing. However, I really would like to keep the ability to, at least, optionally run interpreted code in the same process (without profiling etc). Do you think we could have both?
We can certainly have both, it's straightforward to implement, but I don't get to throw away some of the hacks we have to support same-process execution, which would be a shame. We just add more code rather than
Cheers, Manuel
Simon Marlow
: Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

Simon,
I'd like to hear how we can support what IHaskell does with remote GHCi.
One core functionality that we use dynCompileExpr for (not quite
dynCompileExpr, but similar) is getting the standard output of code that is
being run. Any time code is run, we
1. Create a unix pipe.
2. Set stdout to point to that pipe using dupTo.
3. Use hscStmt with unsafeCoerce to get the other end of the pipe in the
compiled context.
4. Run the statement in the interpreted context in a separate thread;
meanwhile, read from the pipe to get the stdout of the code running in the
interpreted context.
5. When it is done running, move stdout back to point to the read stdout
and close the unix pipe file handle.
6. Send the stdout (both intermediate values and the final value) to the
frontend to display to the user.
The key here is that we can access directly the file handle created by the
interpreted code. If the interpreted code is remote, we clearly cannot read
from a pipe it creates. In your remote GHCi, how could we solve this
problem?
In general, how would stdin and stdout work? Would there be a clean way to
feed the remote process its stdin and receive its stdout and stderr? That
would effectively mean stdin/stdout/stderr are configurable which would be
a godsend for IHaskell.
-- Andrew
On Wed, Nov 18, 2015 at 1:45 AM, Simon Marlow
On 18/11/2015 01:41, Manuel M T Chakravarty wrote:
Hi Simon,
While this is an interesting proposal, Haskell for Mac strongly relies on running interpreted code in the same process. I’m using ’dynCompileExpr’ as well as ’hscStmtWithLocation’ and some other stuff.
Let me say first of all that I'm not going to remove anything, so there's no need to worry. But I'd like to explore exactly what you need, so that we can see whether there's a way to accommodate it with a separate-process implementation.
hscStmtWithLocation is part of the core GHCi functionality, it is definitely supported. It has a slightly different signature:
hscStmtWithLocation :: HscEnv -> String -- ^ The statement -> String -- ^ The source -> Int -- ^ Starting line -> IO ( Maybe ([Id] , RemoteHValue {- IO [HValue] -} , FixityEnv))
RemoteHValue is a reference to a value in the interpreter's context. These have to be evaluated via an explicit API, rather than just unsafeCoercing HValue as we do now. (this is not strictly speaking part of the GHC API, so a separate but interesting question is: why did you need to use this directly, and what should we add to the GHC API?)
I believe that many uses of dynCompileExpr can be changed so that the code using the resulting value is moved into the interpreter's context, and then there's no problem.
This is quite crucial for some of the interactive
functionality. Imagine a game where the game engine is in Swift linked into the main application and the game logic is in *interpreted* Haskell code. The engine calls into the Haskell code multiple times per frame of the animation and for all keyboard/mouse/etc input (using StablePtr and ForeignPtr to construct the scene graph across the Swift and Haskell heap).
So my question is, why wouldn't you run the whole game engine in the interpreter's context? That's what would happen if you were to load the program into GHCi and run it. Directly calling back and forth between the client of the GHC API and the program being interpreted is arguably a strange thing to do, and it's kind of accidental that we allow it.
I actually also might have a use for the architecture that you are
proposing. However, I really would like to keep the ability to, at least, optionally run interpreted code in the same process (without profiling etc). Do you think we could have both?
We can certainly have both, it's straightforward to implement, but I don't get to throw away some of the hacks we have to support same-process execution, which would be a shame. We just add more code rather than
Cheers,
Manuel
Simon Marlow
: Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

Hi Andrew - Since the interpreted code is running in a separate process that we spawn using createProcess, we can set stdin/stdout/stderr to be whatever we like, including new pipes. GHC itself needs two pipes to communicate with the sub-process, but those use separate file descriptors from the std Handles. So I think the answer is yes, we can support that more easily with remote GHCi. I'll think about what API we can provide for it. Cheers, Simon On 18/11/2015 16:26, Andrew Gibiansky wrote:
Simon,
I'd like to hear how we can support what IHaskell does with remote GHCi.
One core functionality that we use dynCompileExpr for (not quite dynCompileExpr, but similar) is getting the standard output of code that is being run. Any time code is run, we
1. Create a unix pipe. 2. Set stdout to point to that pipe using dupTo. 3. Use hscStmt with unsafeCoerce to get the other end of the pipe in the compiled context. 4. Run the statement in the interpreted context in a separate thread; meanwhile, read from the pipe to get the stdout of the code running in the interpreted context. 5. When it is done running, move stdout back to point to the read stdout and close the unix pipe file handle. 6. Send the stdout (both intermediate values and the final value) to the frontend to display to the user.
The key here is that we can access directly the file handle created by the interpreted code. If the interpreted code is remote, we clearly cannot read from a pipe it creates. In your remote GHCi, how could we solve this problem?
In general, how would stdin and stdout work? Would there be a clean way to feed the remote process its stdin and receive its stdout and stderr? That would effectively mean stdin/stdout/stderr are configurable which would be a godsend for IHaskell.
-- Andrew
On Wed, Nov 18, 2015 at 1:45 AM, Simon Marlow
mailto:marlowsd@gmail.com> wrote: On 18/11/2015 01:41, Manuel M T Chakravarty wrote:
Hi Simon,
While this is an interesting proposal, Haskell for Mac strongly relies on running interpreted code in the same process. I’m using ’dynCompileExpr’ as well as ’hscStmtWithLocation’ and some other stuff.
Let me say first of all that I'm not going to remove anything, so there's no need to worry. But I'd like to explore exactly what you need, so that we can see whether there's a way to accommodate it with a separate-process implementation.
hscStmtWithLocation is part of the core GHCi functionality, it is definitely supported. It has a slightly different signature:
hscStmtWithLocation :: HscEnv -> String -- ^ The statement -> String -- ^ The source -> Int -- ^ Starting line -> IO ( Maybe ([Id] , RemoteHValue {- IO [HValue] -} , FixityEnv))
RemoteHValue is a reference to a value in the interpreter's context. These have to be evaluated via an explicit API, rather than just unsafeCoercing HValue as we do now. (this is not strictly speaking part of the GHC API, so a separate but interesting question is: why did you need to use this directly, and what should we add to the GHC API?)
I believe that many uses of dynCompileExpr can be changed so that the code using the resulting value is moved into the interpreter's context, and then there's no problem.
This is quite crucial for some of the interactive functionality. Imagine a game where the game engine is in Swift linked into the main application and the game logic is in *interpreted* Haskell code. The engine calls into the Haskell code multiple times per frame of the animation and for all keyboard/mouse/etc input (using StablePtr and ForeignPtr to construct the scene graph across the Swift and Haskell heap).
So my question is, why wouldn't you run the whole game engine in the interpreter's context? That's what would happen if you were to load the program into GHCi and run it. Directly calling back and forth between the client of the GHC API and the program being interpreted is arguably a strange thing to do, and it's kind of accidental that we allow it.
I actually also might have a use for the architecture that you are proposing. However, I really would like to keep the ability to, at least, optionally run interpreted code in the same process (without profiling etc). Do you think we could have both?
We can certainly have both, it's straightforward to implement, but I don't get to throw away some of the hacks we have to support same-process execution, which would be a shame. We just add more code rather than
Cheers, Manuel
Simon Marlow
mailto:marlowsd@gmail.com>: Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org mailto:ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org mailto:ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

Simon,
That's good to hear. That addresses one of the complex use cases for
dynCompileExpr that we have.
I'd like to present two more and see how we can address them. They both
follow the same pattern so I will just describe the first one.
In order to let interpreted Haskell code display images and other complex
media to the frontend, the interpreted code uses unsafePerformIO to create
a TChan. This TChan holds images (roughly speaking). The interpreted
Haskell has access to a function which writes to this TChan.
The compiled Haskell runs the interpreted Haskell in a separate thread.
That thread then writes to this TChan (which lives in the interpreted
context). In order to access values in the TChan, IHaskell uses
dynCompileExpr on a value of type `IO [Image]`. This value is an IO action
that reads from the TChan that lives in the interpreted context. This value
is then run in the compiled code, giving IHaskell access to the results
generated by the interpreter.
I do not see how this can be easily replicated with a remote GHCi. The
value is `IO [Image]`, so it is not serializable. `[Image]` is
serializable; however, in order to get the Image values from the TChan, we
would have to run interpreted code, and these images are generated during
the runtime of interpreted code already, so we would need to be running two
separate interpreted threads at once. This has to be completely invisible
to the user and seems to me like it might be a logistical nightmare... And,
if I understand correctly, GHC/GHCi are not thread safe, so I can't just
use the new equivalent of dynCompileExpr from two threads. (Can I?)
Thanks,
-- Andrew
On Thu, Nov 19, 2015 at 1:44 AM, Simon Marlow
Hi Andrew -
Since the interpreted code is running in a separate process that we spawn using createProcess, we can set stdin/stdout/stderr to be whatever we like, including new pipes. GHC itself needs two pipes to communicate with the sub-process, but those use separate file descriptors from the std Handles.
So I think the answer is yes, we can support that more easily with remote GHCi. I'll think about what API we can provide for it.
Cheers, Simon
On 18/11/2015 16:26, Andrew Gibiansky wrote:
Simon,
I'd like to hear how we can support what IHaskell does with remote GHCi.
One core functionality that we use dynCompileExpr for (not quite dynCompileExpr, but similar) is getting the standard output of code that is being run. Any time code is run, we
1. Create a unix pipe. 2. Set stdout to point to that pipe using dupTo. 3. Use hscStmt with unsafeCoerce to get the other end of the pipe in the compiled context. 4. Run the statement in the interpreted context in a separate thread; meanwhile, read from the pipe to get the stdout of the code running in the interpreted context. 5. When it is done running, move stdout back to point to the read stdout and close the unix pipe file handle. 6. Send the stdout (both intermediate values and the final value) to the frontend to display to the user.
The key here is that we can access directly the file handle created by the interpreted code. If the interpreted code is remote, we clearly cannot read from a pipe it creates. In your remote GHCi, how could we solve this problem?
In general, how would stdin and stdout work? Would there be a clean way to feed the remote process its stdin and receive its stdout and stderr? That would effectively mean stdin/stdout/stderr are configurable which would be a godsend for IHaskell.
-- Andrew
On Wed, Nov 18, 2015 at 1:45 AM, Simon Marlow
mailto:marlowsd@gmail.com> wrote: On 18/11/2015 01:41, Manuel M T Chakravarty wrote:
Hi Simon,
While this is an interesting proposal, Haskell for Mac strongly relies on running interpreted code in the same process. I’m using ’dynCompileExpr’ as well as ’hscStmtWithLocation’ and some other stuff.
Let me say first of all that I'm not going to remove anything, so there's no need to worry. But I'd like to explore exactly what you need, so that we can see whether there's a way to accommodate it with a separate-process implementation.
hscStmtWithLocation is part of the core GHCi functionality, it is definitely supported. It has a slightly different signature:
hscStmtWithLocation :: HscEnv -> String -- ^ The statement -> String -- ^ The source -> Int -- ^ Starting line -> IO ( Maybe ([Id] , RemoteHValue {- IO [HValue] -} , FixityEnv))
RemoteHValue is a reference to a value in the interpreter's context. These have to be evaluated via an explicit API, rather than just unsafeCoercing HValue as we do now. (this is not strictly speaking part of the GHC API, so a separate but interesting question is: why did you need to use this directly, and what should we add to the GHC API?)
I believe that many uses of dynCompileExpr can be changed so that the code using the resulting value is moved into the interpreter's context, and then there's no problem.
This is quite crucial for some of the interactive functionality. Imagine a game where the game engine is in Swift linked into the main application and the game logic is in *interpreted* Haskell code. The engine calls into the Haskell code multiple times per frame of the animation and for all keyboard/mouse/etc input (using StablePtr and ForeignPtr to construct the scene graph across the Swift and Haskell heap).
So my question is, why wouldn't you run the whole game engine in the interpreter's context? That's what would happen if you were to load the program into GHCi and run it. Directly calling back and forth between the client of the GHC API and the program being interpreted is arguably a strange thing to do, and it's kind of accidental that we allow it.
I actually also might have a use for the architecture that you are proposing. However, I really would like to keep the ability to, at least, optionally run interpreted code in the same process (without profiling etc). Do you think we could have both?
We can certainly have both, it's straightforward to implement, but I don't get to throw away some of the hacks we have to support same-process execution, which would be a shame. We just add more code rather than
Cheers, Manuel
Simon Marlow
:
Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org mailto:ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org mailto:ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

Simon Marlow
: On 18/11/2015 01:41, Manuel M T Chakravarty wrote: Hi Simon,
While this is an interesting proposal, Haskell for Mac strongly relies on running interpreted code in the same process. I’m using ’dynCompileExpr’ as well as ’hscStmtWithLocation’ and some other stuff.
Let me say first of all that I'm not going to remove anything, so there's no need to worry. But I'd like to explore exactly what you need, so that we can see whether there's a way to accommodate it with a separate-process implementation.
hscStmtWithLocation is part of the core GHCi functionality, it is definitely supported. It has a slightly different signature:
hscStmtWithLocation :: HscEnv -> String -- ^ The statement -> String -- ^ The source -> Int -- ^ Starting line -> IO ( Maybe ([Id] , RemoteHValue {- IO [HValue] -} , FixityEnv))
RemoteHValue is a reference to a value in the interpreter's context. These have to be evaluated via an explicit API, rather than just unsafeCoercing Value as we do now. (this is not strictly speaking part of the GHC API, so a separate but interesting question is: why did you need to use this directly, and what should we add to the GHC API?)
The GHC API basically assumes that the ”result” of statement execution is the *side-effect* of printing the result to stdout. This is not sufficient for an interactive graphical environment as (1) I want to have the result (even if it is a string) separate from anything else interpreted code execution writes to stdout. (In Haskell for Mac, these things are displayed in different places.) (2) I want results that are not just strings. For example, a result (of running Haskell code) may be a ForeignPtr to a C-land data structure representing an image (e.g., an in-memory representation of a PNG image rendered by Diagrams). For the latter, I’m actually using `compileExpr`, then `unsafeCoerce` the `hValue` into `IO (ForeignPtr ())` and `try` that (to also catch any exceptions). When this code runs, in some cases, it calls back and forth between interpreted Haskell code and the host application using the FFI.
I believe that many uses of dynCompileExpr can be changed so that the code using the resulting value is moved into the interpreter’s context, and then there’s no problem.
This is difficult in my case, because the resulting value is used in the GUI code written in Swift. Code running in a different process cannot call the Cocoa framework methods for the GUI of the main process.
This is quite crucial for some of the interactive functionality. Imagine a game where the game engine is in Swift linked into the main application and the game logic is in *interpreted* Haskell code. The engine calls into the Haskell code multiple times per frame of the animation and for all keyboard/mouse/etc input (using StablePtr and ForeignPtr to construct the scene graph across the Swift and Haskell heap).
So my question is, why wouldn't you run the whole game engine in the interpreter's context? That’s what would happen if you were to load the program into GHCi and run it.
On a fundamental level: The game engine runs on OpenGL. If it is in a different process, it cannot access the OpenGL context of the main process (which it needs to do to render into a specific view of a specific window of the main process). In practice, it is not just an OpenGL problem as I’m using a framework called SpriteKit with its own event and rendering loop that in turn uses OpenGL for the actual rendering. It does a lot of things behind the scenes (which makes it convenient to use), which requires you to be careful which threads you use to execute some operations. Running in an entire different process is surely going to break things.
Directly calling back and forth between the client of the GHC API and the program being interpreted is arguably a strange thing to do, and it’s kind of accidental that we allow it.
I understand that, but I also think that it is an artefact of Haskell mostly being used in a command line program set up. I don’t think, it is just by chance that the IHaskell people do some quite similar things to at least some of what I’m doing. Once you want a more interactive experience, call patterns get more complicated.
I actually also might have a use for the architecture that you are proposing. However, I really would like to keep the ability to, at least, optionally run interpreted code in the same process (without profiling etc). Do you think we could have both?
We can certainly have both, it's straightforward to implement, but I don't get to throw away some of the hacks we have to support same-process execution, which would be a shame. We just add more code rather than
Yes, I understand that and, as I wrote, I do like the idea of running in a separate process. However, it would also be a shame to prevent richer and more interactive experiences than CLI applications. I have thought a bit more about what the fundamental obstacle is. I think, it is two things: (1) I have interpreted Haskell code that (via a compiled Haskell library) uses FFI calls to call Cocoa system framework methods to create Cocoa objects. In Haskell, these Cocoa objects are referenced via a ForeignPtr and I need the interpreter to be able to return these foreign pointers. The ForeignPtr’s need to refer to memory of the main host process; hence, the FFI calls need to run the Cocoa framework code in the host process. (2) The Cocoa objects from (1) include both StablePtrs as well as C function pointers created via foreign dynamic wrapper. At least some of the StablePtrs refer to Haskell heap structures that need to be accessed by interpreted Haskell code. And calling the dynamic wrapper code from Swift in the main process needs to execute Haskell code that may refer to closures created by interpreted code. So, the issue really is that I would need FFI calls in the interpreter process that call Cocoa code in the main process and dynamic wrapper entry code in the main process that needs to call Haskell code in the interpreter process. (Crossing the FFI language chasm corresponds to cross-process calls.) I cannot move the Cocoa code from the main process to the interpreter process, as Cocoa requires that it runs on the *main* thread of the main process (to interact with the GUI and also to render via OpenGL). Does that make sense? Cheers, Manuel
Simon Marlow
: Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

Hi Manuel, Thanks for the detailed reply, I have a much better understanding of your requirements now. I'm going to support both models of running interpreted code. The current plan is to have a flag, -fexternal-interpreter, which GHC will use by default when running Template Haskell during compilation, and perhaps for GHCi, but for compatibility with applications like yours I'll probably leave it off for GHC API users. There's really no downside to doing this, it's not much more complicated than implementing the separate-process model. Cheers, Simon On 21/11/2015 03:38, Manuel M T Chakravarty wrote:
Simon Marlow
: On 18/11/2015 01:41, Manuel M T Chakravarty wrote: Hi Simon,
While this is an interesting proposal, Haskell for Mac strongly relies on running interpreted code in the same process. I’m using ’dynCompileExpr’ as well as ’hscStmtWithLocation’ and some other stuff.
Let me say first of all that I'm not going to remove anything, so there's no need to worry. But I'd like to explore exactly what you need, so that we can see whether there's a way to accommodate it with a separate-process implementation.
hscStmtWithLocation is part of the core GHCi functionality, it is definitely supported. It has a slightly different signature:
hscStmtWithLocation :: HscEnv -> String -- ^ The statement -> String -- ^ The source -> Int -- ^ Starting line -> IO ( Maybe ([Id] , RemoteHValue {- IO [HValue] -} , FixityEnv))
RemoteHValue is a reference to a value in the interpreter's context. These have to be evaluated via an explicit API, rather than just unsafeCoercing Value as we do now. (this is not strictly speaking part of the GHC API, so a separate but interesting question is: why did you need to use this directly, and what should we add to the GHC API?)
The GHC API basically assumes that the ”result” of statement execution is the *side-effect* of printing the result to stdout. This is not sufficient for an interactive graphical environment as
(1) I want to have the result (even if it is a string) separate from anything else interpreted code execution writes to stdout. (In Haskell for Mac, these things are displayed in different places.)
(2) I want results that are not just strings. For example, a result (of running Haskell code) may be a ForeignPtr to a C-land data structure representing an image (e.g., an in-memory representation of a PNG image rendered by Diagrams).
For the latter, I’m actually using `compileExpr`, then `unsafeCoerce` the `hValue` into `IO (ForeignPtr ())` and `try` that (to also catch any exceptions). When this code runs, in some cases, it calls back and forth between interpreted Haskell code and the host application using the FFI.
I believe that many uses of dynCompileExpr can be changed so that the code using the resulting value is moved into the interpreter’s context, and then there’s no problem.
This is difficult in my case, because the resulting value is used in the GUI code written in Swift. Code running in a different process cannot call the Cocoa framework methods for the GUI of the main process.
This is quite crucial for some of the interactive functionality. Imagine a game where the game engine is in Swift linked into the main application and the game logic is in *interpreted* Haskell code. The engine calls into the Haskell code multiple times per frame of the animation and for all keyboard/mouse/etc input (using StablePtr and ForeignPtr to construct the scene graph across the Swift and Haskell heap).
So my question is, why wouldn't you run the whole game engine in the interpreter's context? That’s what would happen if you were to load the program into GHCi and run it.
On a fundamental level: The game engine runs on OpenGL. If it is in a different process, it cannot access the OpenGL context of the main process (which it needs to do to render into a specific view of a specific window of the main process).
In practice, it is not just an OpenGL problem as I’m using a framework called SpriteKit with its own event and rendering loop that in turn uses OpenGL for the actual rendering. It does a lot of things behind the scenes (which makes it convenient to use), which requires you to be careful which threads you use to execute some operations. Running in an entire different process is surely going to break things.
Directly calling back and forth between the client of the GHC API and the program being interpreted is arguably a strange thing to do, and it’s kind of accidental that we allow it.
I understand that, but I also think that it is an artefact of Haskell mostly being used in a command line program set up. I don’t think, it is just by chance that the IHaskell people do some quite similar things to at least some of what I’m doing. Once you want a more interactive experience, call patterns get more complicated.
I actually also might have a use for the architecture that you are proposing. However, I really would like to keep the ability to, at least, optionally run interpreted code in the same process (without profiling etc). Do you think we could have both?
We can certainly have both, it's straightforward to implement, but I don't get to throw away some of the hacks we have to support same-process execution, which would be a shame. We just add more code rather than
Yes, I understand that and, as I wrote, I do like the idea of running in a separate process. However, it would also be a shame to prevent richer and more interactive experiences than CLI applications.
I have thought a bit more about what the fundamental obstacle is. I think, it is two things:
(1) I have interpreted Haskell code that (via a compiled Haskell library) uses FFI calls to call Cocoa system framework methods to create Cocoa objects. In Haskell, these Cocoa objects are referenced via a ForeignPtr and I need the interpreter to be able to return these foreign pointers. The ForeignPtr’s need to refer to memory of the main host process; hence, the FFI calls need to run the Cocoa framework code in the host process.
(2) The Cocoa objects from (1) include both StablePtrs as well as C function pointers created via foreign dynamic wrapper. At least some of the StablePtrs refer to Haskell heap structures that need to be accessed by interpreted Haskell code. And calling the dynamic wrapper code from Swift in the main process needs to execute Haskell code that may refer to closures created by interpreted code.
So, the issue really is that I would need FFI calls in the interpreter process that call Cocoa code in the main process and dynamic wrapper entry code in the main process that needs to call Haskell code in the interpreter process. (Crossing the FFI language chasm corresponds to cross-process calls.)
I cannot move the Cocoa code from the main process to the interpreter process, as Cocoa requires that it runs on the *main* thread of the main process (to interact with the GUI and also to render via OpenGL).
Does that make sense?
Cheers, Manuel
Simon Marlow
: Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

Hi Simon, Sounds great! This may very well what you have got in mind anyway, but I could imagine to run the interpreter on a different thread in the -fno-external-interpreter case and arrange communication through the same messaging API that you outlined for the seperate-process interpreter. Then, the essential difference between the two modes would be whether memory is shared or not (i.e., multithreading vs multi-process). Cheers, Manuel
Simon Marlow
: Hi Manuel,
Thanks for the detailed reply, I have a much better understanding of your requirements now.
I'm going to support both models of running interpreted code. The current plan is to have a flag, -fexternal-interpreter, which GHC will use by default when running Template Haskell during compilation, and perhaps for GHCi, but for compatibility with applications like yours I'll probably leave it off for GHC API users.
There's really no downside to doing this, it's not much more complicated than implementing the separate-process model.
Cheers, Simon
On 21/11/2015 03:38, Manuel M T Chakravarty wrote:
Simon Marlow
: On 18/11/2015 01:41, Manuel M T Chakravarty wrote: Hi Simon,
While this is an interesting proposal, Haskell for Mac strongly relies on running interpreted code in the same process. I’m using ’dynCompileExpr’ as well as ’hscStmtWithLocation’ and some other stuff.
Let me say first of all that I'm not going to remove anything, so there's no need to worry. But I'd like to explore exactly what you need, so that we can see whether there's a way to accommodate it with a separate-process implementation.
hscStmtWithLocation is part of the core GHCi functionality, it is definitely supported. It has a slightly different signature:
hscStmtWithLocation :: HscEnv -> String -- ^ The statement -> String -- ^ The source -> Int -- ^ Starting line -> IO ( Maybe ([Id] , RemoteHValue {- IO [HValue] -} , FixityEnv))
RemoteHValue is a reference to a value in the interpreter's context. These have to be evaluated via an explicit API, rather than just unsafeCoercing Value as we do now. (this is not strictly speaking part of the GHC API, so a separate but interesting question is: why did you need to use this directly, and what should we add to the GHC API?)
The GHC API basically assumes that the ”result” of statement execution is the *side-effect* of printing the result to stdout. This is not sufficient for an interactive graphical environment as
(1) I want to have the result (even if it is a string) separate from anything else interpreted code execution writes to stdout. (In Haskell for Mac, these things are displayed in different places.)
(2) I want results that are not just strings. For example, a result (of running Haskell code) may be a ForeignPtr to a C-land data structure representing an image (e.g., an in-memory representation of a PNG image rendered by Diagrams).
For the latter, I’m actually using `compileExpr`, then `unsafeCoerce` the `hValue` into `IO (ForeignPtr ())` and `try` that (to also catch any exceptions). When this code runs, in some cases, it calls back and forth between interpreted Haskell code and the host application using the FFI.
I believe that many uses of dynCompileExpr can be changed so that the code using the resulting value is moved into the interpreter’s context, and then there’s no problem.
This is difficult in my case, because the resulting value is used in the GUI code written in Swift. Code running in a different process cannot call the Cocoa framework methods for the GUI of the main process.
This is quite crucial for some of the interactive functionality. Imagine a game where the game engine is in Swift linked into the main application and the game logic is in *interpreted* Haskell code. The engine calls into the Haskell code multiple times per frame of the animation and for all keyboard/mouse/etc input (using StablePtr and ForeignPtr to construct the scene graph across the Swift and Haskell heap).
So my question is, why wouldn't you run the whole game engine in the interpreter's context? That’s what would happen if you were to load the program into GHCi and run it.
On a fundamental level: The game engine runs on OpenGL. If it is in a different process, it cannot access the OpenGL context of the main process (which it needs to do to render into a specific view of a specific window of the main process).
In practice, it is not just an OpenGL problem as I’m using a framework called SpriteKit with its own event and rendering loop that in turn uses OpenGL for the actual rendering. It does a lot of things behind the scenes (which makes it convenient to use), which requires you to be careful which threads you use to execute some operations. Running in an entire different process is surely going to break things.
Directly calling back and forth between the client of the GHC API and the program being interpreted is arguably a strange thing to do, and it’s kind of accidental that we allow it.
I understand that, but I also think that it is an artefact of Haskell mostly being used in a command line program set up. I don’t think, it is just by chance that the IHaskell people do some quite similar things to at least some of what I’m doing. Once you want a more interactive experience, call patterns get more complicated.
I actually also might have a use for the architecture that you are proposing. However, I really would like to keep the ability to, at least, optionally run interpreted code in the same process (without profiling etc). Do you think we could have both?
We can certainly have both, it's straightforward to implement, but I don't get to throw away some of the hacks we have to support same-process execution, which would be a shame. We just add more code rather than
Yes, I understand that and, as I wrote, I do like the idea of running in a separate process. However, it would also be a shame to prevent richer and more interactive experiences than CLI applications.
I have thought a bit more about what the fundamental obstacle is. I think, it is two things:
(1) I have interpreted Haskell code that (via a compiled Haskell library) uses FFI calls to call Cocoa system framework methods to create Cocoa objects. In Haskell, these Cocoa objects are referenced via a ForeignPtr and I need the interpreter to be able to return these foreign pointers. The ForeignPtr’s need to refer to memory of the main host process; hence, the FFI calls need to run the Cocoa framework code in the host process.
(2) The Cocoa objects from (1) include both StablePtrs as well as C function pointers created via foreign dynamic wrapper. At least some of the StablePtrs refer to Haskell heap structures that need to be accessed by interpreted Haskell code. And calling the dynamic wrapper code from Swift in the main process needs to execute Haskell code that may refer to closures created by interpreted code.
So, the issue really is that I would need FFI calls in the interpreter process that call Cocoa code in the main process and dynamic wrapper entry code in the main process that needs to call Haskell code in the interpreter process. (Crossing the FFI language chasm corresponds to cross-process calls.)
I cannot move the Cocoa code from the main process to the interpreter process, as Cocoa requires that it runs on the *main* thread of the main process (to interact with the GUI and also to render via OpenGL).
Does that make sense?
Cheers, Manuel
Simon Marlow
: Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

What kind of timescale can we expect on this, and will it be possible to backport it (via a ghci-ng or similar)? We are currently wrestling with ghci stdio issues in haskell-ide-engine. If this will be out soon we can wait for it. Alan On Tue, Nov 24, 2015 at 2:25 AM, Manuel M T Chakravarty < chak@justtesting.org> wrote:
Hi Simon,
Sounds great!
This may very well what you have got in mind anyway, but I could imagine to run the interpreter on a different thread in the -fno-external-interpreter case and arrange communication through the same messaging API that you outlined for the seperate-process interpreter. Then, the essential difference between the two modes would be whether memory is shared or not (i.e., multithreading vs multi-process).
Cheers, Manuel
Simon Marlow
: Hi Manuel,
Thanks for the detailed reply, I have a much better understanding of your requirements now.
I'm going to support both models of running interpreted code. The current plan is to have a flag, -fexternal-interpreter, which GHC will use by default when running Template Haskell during compilation, and perhaps for GHCi, but for compatibility with applications like yours I'll probably leave it off for GHC API users.
There's really no downside to doing this, it's not much more complicated than implementing the separate-process model.
Cheers, Simon
Simon Marlow
: On 18/11/2015 01:41, Manuel M T Chakravarty wrote: Hi Simon,
While this is an interesting proposal, Haskell for Mac strongly relies on running interpreted code in the same process. I’m using ’dynCompileExpr’ as well as ’hscStmtWithLocation’ and some other stuff.
Let me say first of all that I'm not going to remove anything, so
hscStmtWithLocation is part of the core GHCi functionality, it is
definitely supported. It has a slightly different signature:
hscStmtWithLocation :: HscEnv -> String -- ^ The statement -> String -- ^ The source -> Int -- ^ Starting line -> IO ( Maybe ([Id] , RemoteHValue {- IO [HValue] -} , FixityEnv))
RemoteHValue is a reference to a value in the interpreter's context.
These have to be evaluated via an explicit API, rather than just unsafeCoercing Value as we do now. (this is not strictly speaking part of
On 21/11/2015 03:38, Manuel M T Chakravarty wrote: there's no need to worry. But I'd like to explore exactly what you need, so that we can see whether there's a way to accommodate it with a separate-process implementation. the GHC API, so a separate but interesting question is: why did you need to use this directly, and what should we add to the GHC API?)
The GHC API basically assumes that the ”result” of statement execution
is the *side-effect* of printing the result to stdout. This is not sufficient for an interactive graphical environment as
(1) I want to have the result (even if it is a string) separate from
anything else interpreted code execution writes to stdout. (In Haskell for Mac, these things are displayed in different places.)
(2) I want results that are not just strings. For example, a result (of
running Haskell code) may be a ForeignPtr to a C-land data structure representing an image (e.g., an in-memory representation of a PNG image rendered by Diagrams).
For the latter, I’m actually using `compileExpr`, then `unsafeCoerce`
the `hValue` into `IO (ForeignPtr ())` and `try` that (to also catch any exceptions). When this code runs, in some cases, it calls back and forth between interpreted Haskell code and the host application using the FFI.
I believe that many uses of dynCompileExpr can be changed so that the
code using the resulting value is moved into the interpreter’s context, and then there’s no problem.
This is difficult in my case, because the resulting value is used in
the GUI code written in Swift. Code running in a different process cannot call the Cocoa framework methods for the GUI of the main process.
This is quite crucial for some of the interactive functionality. Imagine a game where the game engine is in Swift linked into the main application and the game logic is in *interpreted* Haskell code. The engine calls into the Haskell code multiple times per frame of the animation and for all keyboard/mouse/etc input (using StablePtr and ForeignPtr to construct the scene graph across the Swift and Haskell heap).
So my question is, why wouldn't you run the whole game engine in the
interpreter's context? That’s what would happen if you were to load the program into GHCi and run it.
On a fundamental level: The game engine runs on OpenGL. If it is in a
different process, it cannot access the OpenGL context of the main process (which it needs to do to render into a specific view of a specific window of the main process).
In practice, it is not just an OpenGL problem as I’m using a framework
called SpriteKit with its own event and rendering loop that in turn uses OpenGL for the actual rendering. It does a lot of things behind the scenes (which makes it convenient to use), which requires you to be careful which threads you use to execute some operations. Running in an entire different process is surely going to break things.
Directly calling back and forth between the client of the GHC API
and the program being interpreted is arguably a strange thing to do, and it’s kind of accidental that we allow it.
I understand that, but I also think that it is an artefact of Haskell
mostly being used in a command line program set up. I don’t think, it is just by chance that the IHaskell people do some quite similar things to at least some of what I’m doing. Once you want a more interactive experience, call patterns get more complicated.
I actually also might have a use for the architecture that you are proposing. However, I really would like to keep the ability to, at least, optionally run interpreted code in the same process (without profiling etc). Do you think we could have both?
We can certainly have both, it's straightforward to implement, but I
don't get to throw away some of the hacks we have to support same-process execution, which would be a shame. We just add more code rather than
Yes, I understand that and, as I wrote, I do like the idea of running
in a separate process. However, it would also be a shame to prevent richer and more interactive experiences than CLI applications.
I have thought a bit more about what the fundamental obstacle is. I
think, it is two things:
(1) I have interpreted Haskell code that (via a compiled Haskell
library) uses FFI calls to call Cocoa system framework methods to create Cocoa objects. In Haskell, these Cocoa objects are referenced via a ForeignPtr and I need the interpreter to be able to return these foreign pointers. The ForeignPtr’s need to refer to memory of the main host process; hence, the FFI calls need to run the Cocoa framework code in the host process.
(2) The Cocoa objects from (1) include both StablePtrs as well as C
function pointers created via foreign dynamic wrapper. At least some of the StablePtrs refer to Haskell heap structures that need to be accessed by interpreted Haskell code. And calling the dynamic wrapper code from Swift in the main process needs to execute Haskell code that may refer to closures created by interpreted code.
So, the issue really is that I would need FFI calls in the interpreter
process that call Cocoa code in the main process and dynamic wrapper entry code in the main process that needs to call Haskell code in the interpreter process. (Crossing the FFI language chasm corresponds to cross-process calls.)
I cannot move the Cocoa code from the main process to the interpreter
process, as Cocoa requires that it runs on the *main* thread of the main process (to interact with the GUI and also to render via OpenGL).
Does that make sense?
Cheers, Manuel
Simon Marlow
: Hi folks - I've been thinking about changing the way we run
I summarised the idea here:
https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this,
interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime. particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

I want to get it done within the next few weeks. Currently GHCi is mostly working, and the main missing pieces are TH and the debugger. I plan to backport it to the 7.10 branch so that I can have it in our local GHC builds at Facebook. My WIP branch is here: https://github.com/simonmar/ghc/commits/prof-ghci Cheers Simon On 24/11/2015 11:04, Alan & Kim Zimmerman wrote:
What kind of timescale can we expect on this, and will it be possible to backport it (via a ghci-ng or similar)?
We are currently wrestling with ghci stdio issues in haskell-ide-engine. If this will be out soon we can wait for it.
Alan
On Tue, Nov 24, 2015 at 2:25 AM, Manuel M T Chakravarty
mailto:chak@justtesting.org> wrote: Hi Simon,
Sounds great!
This may very well what you have got in mind anyway, but I could imagine to run the interpreter on a different thread in the -fno-external-interpreter case and arrange communication through the same messaging API that you outlined for the seperate-process interpreter. Then, the essential difference between the two modes would be whether memory is shared or not (i.e., multithreading vs multi-process).
Cheers, Manuel
> Simon Marlow
mailto:marlowsd@gmail.com>: > > Hi Manuel, > > Thanks for the detailed reply, I have a much better understanding of your requirements now. > > I'm going to support both models of running interpreted code. The current plan is to have a flag, -fexternal-interpreter, which GHC will use by default when running Template Haskell during compilation, and perhaps for GHCi, but for compatibility with applications like yours I'll probably leave it off for GHC API users. > > There's really no downside to doing this, it's not much more complicated than implementing the separate-process model. > > Cheers, > Simon > > On 21/11/2015 03:38, Manuel M T Chakravarty wrote: >>> Simon Marlow mailto:marlowsd@gmail.com>: >>> On 18/11/2015 01:41, Manuel M T Chakravarty wrote: >>>> Hi Simon, >>>> >>>> While this is an interesting proposal, Haskell for Mac strongly >>>> relies on running interpreted code in the same process. I’m using >>>> ’dynCompileExpr’ as well as ’hscStmtWithLocation’ and some other >>>> stuff. >>> >>> Let me say first of all that I'm not going to remove anything, so there's no need to worry. But I'd like to explore exactly what you need, so that we can see whether there's a way to accommodate it with a separate-process implementation. >>> >>> hscStmtWithLocation is part of the core GHCi functionality, it is definitely supported. It has a slightly different signature: >>> >>> hscStmtWithLocation :: HscEnv >>> -> String -- ^ The statement >>> -> String -- ^ The source >>> -> Int -- ^ Starting line >>> -> IO ( Maybe ([Id] >>> , RemoteHValue {- IO [HValue] -} >>> , FixityEnv)) >>> >>> RemoteHValue is a reference to a value in the interpreter's context. These have to be evaluated via an explicit API, rather than just unsafeCoercing Value as we do now. (this is not strictly speaking part of the GHC API, so a separate but interesting question is: why did you need to use this directly, and what should we add to the GHC API?) >> >> The GHC API basically assumes that the ”result” of statement execution is the *side-effect* of printing the result to stdout. This is not sufficient for an interactive graphical environment as >> >> (1) I want to have the result (even if it is a string) separate from anything else interpreted code execution writes to stdout. (In Haskell for Mac, these things are displayed in different places.) >> >> (2) I want results that are not just strings. For example, a result (of running Haskell code) may be a ForeignPtr to a C-land data structure representing an image (e.g., an in-memory representation of a PNG image rendered by Diagrams). >> >> For the latter, I’m actually using `compileExpr`, then `unsafeCoerce` the `hValue` into `IO (ForeignPtr ())` and `try` that (to also catch any exceptions). When this code runs, in some cases, it calls back and forth between interpreted Haskell code and the host application using the FFI. >> >>> I believe that many uses of dynCompileExpr can be changed so that the code using the resulting value is moved into the interpreter’s context, and then there’s no problem. >> >> This is difficult in my case, because the resulting value is used in the GUI code written in Swift. Code running in a different process cannot call the Cocoa framework methods for the GUI of the main process. >> >>>> This is quite crucial for some of the interactive >>>> functionality. Imagine a game where the game engine is in Swift >>>> linked into the main application and the game logic is in >>>> *interpreted* Haskell code. The engine calls into the Haskell code >>>> multiple times per frame of the animation and for all >>>> keyboard/mouse/etc input (using StablePtr and ForeignPtr to construct >>>> the scene graph across the Swift and Haskell heap). >>> >>> So my question is, why wouldn't you run the whole game engine in the interpreter's context? That’s what would happen if you were to load the program into GHCi and run it. >> >> On a fundamental level: The game engine runs on OpenGL. If it is in a different process, it cannot access the OpenGL context of the main process (which it needs to do to render into a specific view of a specific window of the main process). >> >> In practice, it is not just an OpenGL problem as I’m using a framework called SpriteKit with its own event and rendering loop that in turn uses OpenGL for the actual rendering. It does a lot of things behind the scenes (which makes it convenient to use), which requires you to be careful which threads you use to execute some operations. Running in an entire different process is surely going to break things. >> >>> Directly calling back and forth between the client of the GHC API and the program being interpreted is arguably a strange thing to do, and it’s kind of accidental that we allow it. >> >> I understand that, but I also think that it is an artefact of Haskell mostly being used in a command line program set up. I don’t think, it is just by chance that the IHaskell people do some quite similar things to at least some of what I’m doing. Once you want a more interactive experience, call patterns get more complicated. >> >>>> I actually also might have a use for the architecture that you are >>>> proposing. However, I really would like to keep the ability to, at >>>> least, optionally run interpreted code in the same process (without >>>> profiling etc). Do you think we could have both? >>> >>> We can certainly have both, it's straightforward to implement, but I don't get to throw away some of the hacks we have to support same-process execution, which would be a shame. We just add more code rather than >> >> Yes, I understand that and, as I wrote, I do like the idea of running in a separate process. However, it would also be a shame to prevent richer and more interactive experiences than CLI applications. >> >> I have thought a bit more about what the fundamental obstacle is. I think, it is two things: >> >> (1) I have interpreted Haskell code that (via a compiled Haskell library) uses FFI calls to call Cocoa system framework methods to create Cocoa objects. In Haskell, these Cocoa objects are referenced via a ForeignPtr and I need the interpreter to be able to return these foreign pointers. The ForeignPtr’s need to refer to memory of the main host process; hence, the FFI calls need to run the Cocoa framework code in the host process. >> >> (2) The Cocoa objects from (1) include both StablePtrs as well as C function pointers created via foreign dynamic wrapper. At least some of the StablePtrs refer to Haskell heap structures that need to be accessed by interpreted Haskell code. And calling the dynamic wrapper code from Swift in the main process needs to execute Haskell code that may refer to closures created by interpreted code. >> >> So, the issue really is that I would need FFI calls in the interpreter process that call Cocoa code in the main process and dynamic wrapper entry code in the main process that needs to call Haskell code in the interpreter process. (Crossing the FFI language chasm corresponds to cross-process calls.) >> >> I cannot move the Cocoa code from the main process to the interpreter process, as Cocoa requires that it runs on the *main* thread of the main process (to interact with the GUI and also to render via OpenGL). >> >> Does that make sense? >> >> Cheers, >> Manuel >> >>>>> Simon Marlow mailto:marlowsd@gmail.com>: >>>>> >>>>> Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime. >>>>> >>>>> I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi >>>>> >>>>> I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything? >>>>> >>>>> Cheers, >>>>> Simon >>>>> _______________________________________________ >>>>> ghc-devs mailing list >>>>> ghc-devs@haskell.org mailto:ghc-devs@haskell.org >>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs >>>> >> > _______________________________________________ > ghc-devs mailing list > ghc-devs@haskell.org mailto:ghc-devs@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org mailto:ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

It's even easier than that: if there's an API for sending messages and an API for executing messages, then the former just calls the latter directly in the single-process case. Cheers Simon On 24/11/2015 00:25, Manuel M T Chakravarty wrote:
Hi Simon,
Sounds great!
This may very well what you have got in mind anyway, but I could imagine to run the interpreter on a different thread in the -fno-external-interpreter case and arrange communication through the same messaging API that you outlined for the seperate-process interpreter. Then, the essential difference between the two modes would be whether memory is shared or not (i.e., multithreading vs multi-process).
Cheers, Manuel
Simon Marlow
: Hi Manuel,
Thanks for the detailed reply, I have a much better understanding of your requirements now.
I'm going to support both models of running interpreted code. The current plan is to have a flag, -fexternal-interpreter, which GHC will use by default when running Template Haskell during compilation, and perhaps for GHCi, but for compatibility with applications like yours I'll probably leave it off for GHC API users.
There's really no downside to doing this, it's not much more complicated than implementing the separate-process model.
Cheers, Simon
On 21/11/2015 03:38, Manuel M T Chakravarty wrote:
Simon Marlow
: On 18/11/2015 01:41, Manuel M T Chakravarty wrote: Hi Simon,
While this is an interesting proposal, Haskell for Mac strongly relies on running interpreted code in the same process. I’m using ’dynCompileExpr’ as well as ’hscStmtWithLocation’ and some other stuff.
Let me say first of all that I'm not going to remove anything, so there's no need to worry. But I'd like to explore exactly what you need, so that we can see whether there's a way to accommodate it with a separate-process implementation.
hscStmtWithLocation is part of the core GHCi functionality, it is definitely supported. It has a slightly different signature:
hscStmtWithLocation :: HscEnv -> String -- ^ The statement -> String -- ^ The source -> Int -- ^ Starting line -> IO ( Maybe ([Id] , RemoteHValue {- IO [HValue] -} , FixityEnv))
RemoteHValue is a reference to a value in the interpreter's context. These have to be evaluated via an explicit API, rather than just unsafeCoercing Value as we do now. (this is not strictly speaking part of the GHC API, so a separate but interesting question is: why did you need to use this directly, and what should we add to the GHC API?)
The GHC API basically assumes that the ”result” of statement execution is the *side-effect* of printing the result to stdout. This is not sufficient for an interactive graphical environment as
(1) I want to have the result (even if it is a string) separate from anything else interpreted code execution writes to stdout. (In Haskell for Mac, these things are displayed in different places.)
(2) I want results that are not just strings. For example, a result (of running Haskell code) may be a ForeignPtr to a C-land data structure representing an image (e.g., an in-memory representation of a PNG image rendered by Diagrams).
For the latter, I’m actually using `compileExpr`, then `unsafeCoerce` the `hValue` into `IO (ForeignPtr ())` and `try` that (to also catch any exceptions). When this code runs, in some cases, it calls back and forth between interpreted Haskell code and the host application using the FFI.
I believe that many uses of dynCompileExpr can be changed so that the code using the resulting value is moved into the interpreter’s context, and then there’s no problem.
This is difficult in my case, because the resulting value is used in the GUI code written in Swift. Code running in a different process cannot call the Cocoa framework methods for the GUI of the main process.
This is quite crucial for some of the interactive functionality. Imagine a game where the game engine is in Swift linked into the main application and the game logic is in *interpreted* Haskell code. The engine calls into the Haskell code multiple times per frame of the animation and for all keyboard/mouse/etc input (using StablePtr and ForeignPtr to construct the scene graph across the Swift and Haskell heap).
So my question is, why wouldn't you run the whole game engine in the interpreter's context? That’s what would happen if you were to load the program into GHCi and run it.
On a fundamental level: The game engine runs on OpenGL. If it is in a different process, it cannot access the OpenGL context of the main process (which it needs to do to render into a specific view of a specific window of the main process).
In practice, it is not just an OpenGL problem as I’m using a framework called SpriteKit with its own event and rendering loop that in turn uses OpenGL for the actual rendering. It does a lot of things behind the scenes (which makes it convenient to use), which requires you to be careful which threads you use to execute some operations. Running in an entire different process is surely going to break things.
Directly calling back and forth between the client of the GHC API and the program being interpreted is arguably a strange thing to do, and it’s kind of accidental that we allow it.
I understand that, but I also think that it is an artefact of Haskell mostly being used in a command line program set up. I don’t think, it is just by chance that the IHaskell people do some quite similar things to at least some of what I’m doing. Once you want a more interactive experience, call patterns get more complicated.
I actually also might have a use for the architecture that you are proposing. However, I really would like to keep the ability to, at least, optionally run interpreted code in the same process (without profiling etc). Do you think we could have both?
We can certainly have both, it's straightforward to implement, but I don't get to throw away some of the hacks we have to support same-process execution, which would be a shame. We just add more code rather than
Yes, I understand that and, as I wrote, I do like the idea of running in a separate process. However, it would also be a shame to prevent richer and more interactive experiences than CLI applications.
I have thought a bit more about what the fundamental obstacle is. I think, it is two things:
(1) I have interpreted Haskell code that (via a compiled Haskell library) uses FFI calls to call Cocoa system framework methods to create Cocoa objects. In Haskell, these Cocoa objects are referenced via a ForeignPtr and I need the interpreter to be able to return these foreign pointers. The ForeignPtr’s need to refer to memory of the main host process; hence, the FFI calls need to run the Cocoa framework code in the host process.
(2) The Cocoa objects from (1) include both StablePtrs as well as C function pointers created via foreign dynamic wrapper. At least some of the StablePtrs refer to Haskell heap structures that need to be accessed by interpreted Haskell code. And calling the dynamic wrapper code from Swift in the main process needs to execute Haskell code that may refer to closures created by interpreted code.
So, the issue really is that I would need FFI calls in the interpreter process that call Cocoa code in the main process and dynamic wrapper entry code in the main process that needs to call Haskell code in the interpreter process. (Crossing the FFI language chasm corresponds to cross-process calls.)
I cannot move the Cocoa code from the main process to the interpreter process, as Cocoa requires that it runs on the *main* thread of the main process (to interact with the GUI and also to render via OpenGL).
Does that make sense?
Cheers, Manuel
Simon Marlow
: Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

I was reviewing some history here, and I realized that the GHCJS folks had previous implemented this: https://mail.haskell.org/pipermail/ghc-devs/2015-November/010478.html What ever happened to this line of work? Does remote GHCi subsume it? Edward Excerpts from Simon Marlow's message of 2015-11-17 02:10:55 -0800:
Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon

I’m not sure how much I can actually contribute to this, but I’ll just add a few pointers to nothing gets lost. I’m not very familiar with remote ghci, but I think that there is some overlap between remote ghci and out of process template haskell compilation[1][2]. Most of ghcjs’s TH code is in src/Gen2/TH.hs. To be honest, I haven’t had much time last year to do anything for the out of process th stuff. I’m planing to get back at oopth, once we got shaking-up-ghc[3] to build cross compilers properly. From the looks of it, that could be soon :) I only know about the ghcjs repl[4] through twitter. I’m certain luite can share a lot more here. With respect to remote ghci, I haven’t had much time to look into it. The main focus of out of process th (for me) was getting TH to work for cross compiler, which means shipping code to a remote process through some kind of channel that the remote allows*. Hope this might help in some way. Cheers, Moritz [1]: https://github.com/ghcjs/ghcjs/wiki/Porting-GHCJS-Template-Haskell-to-GHC [2]: https://github.com/angerman/oopth [3]: https://github.com/snowleopard/shaking-up-ghc [4]: https://twitter.com/acid2/status/614076905990582272/photo/1 [*]: E.g. getting this to work for iOS.
On Jan 8, 2016, at 2:01 PM, Edward Z. Yang
wrote: I was reviewing some history here, and I realized that the GHCJS folks had previous implemented this:
https://mail.haskell.org/pipermail/ghc-devs/2015-November/010478.html
What ever happened to this line of work? Does remote GHCi subsume it?
Edward
Excerpts from Simon Marlow's message of 2015-11-17 02:10:55 -0800:
Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon

Yes, I used the GHCJS code as a starting point for Remote GHCi - the implementation of TH in Remote GHCi is very similar to GHCJS. Luite and I have chatted about this in person, and I believe he intends to try to merge them at some point. Remote GHCi should make it possible to do TH with a cross-compiler, though you still need to be able to run code on the target platform at compile-time, like GHCJS does with nodejs. Cheers, Simon On 08/01/2016 07:18, Moritz Angermann wrote:
I’m not sure how much I can actually contribute to this, but I’ll just add a few pointers to nothing gets lost. I’m not very familiar with remote ghci, but I think that there is some overlap between remote ghci and out of process template haskell compilation[1][2]. Most of ghcjs’s TH code is in src/Gen2/TH.hs.
To be honest, I haven’t had much time last year to do anything for the out of process th stuff. I’m planing to get back at oopth, once we got shaking-up-ghc[3] to build cross compilers properly. From the looks of it, that could be soon :)
I only know about the ghcjs repl[4] through twitter. I’m certain luite can share a lot more here.
With respect to remote ghci, I haven’t had much time to look into it. The main focus of out of process th (for me) was getting TH to work for cross compiler, which means shipping code to a remote process through some kind of channel that the remote allows*.
Hope this might help in some way.
Cheers, Moritz
[1]: https://github.com/ghcjs/ghcjs/wiki/Porting-GHCJS-Template-Haskell-to-GHC [2]: https://github.com/angerman/oopth [3]: https://github.com/snowleopard/shaking-up-ghc [4]: https://twitter.com/acid2/status/614076905990582272/photo/1 [*]: E.g. getting this to work for iOS.
On Jan 8, 2016, at 2:01 PM, Edward Z. Yang
wrote: I was reviewing some history here, and I realized that the GHCJS folks had previous implemented this:
https://mail.haskell.org/pipermail/ghc-devs/2015-November/010478.html
What ever happened to this line of work? Does remote GHCi subsume it?
Edward
Excerpts from Simon Marlow's message of 2015-11-17 02:10:55 -0800:
Hi folks - I've been thinking about changing the way we run interpreted code so that it would be run in a separate process. It turns out this has quite a few benefits, and would let us kill some of the really awkward hacks we have in GHC to work around problems that arise because we're running interpreted code and the compiler on the same runtime.
I summarised the idea here: https://ghc.haskell.org/trac/ghc/wiki/RemoteGHCi
I'd be interested to hear if anyone has any thoughts around this, particularly if doing this would make your life difficult in some way. Are people relying on dynCompileExpr for anything?
Cheers, Simon
participants (9)
-
Alan & Kim Zimmerman
-
Andrew Gibiansky
-
Edward Z. Yang
-
Luite Stegeman
-
Manuel M T Chakravarty
-
Moritz Angermann
-
Richard Eisenberg
-
Simon Marlow
-
Sumit Sahrawat, Maths & Computing, IIT (BHU)