Remote GHCi

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
28 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: Remote GHCi

Simon Marlow-7
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 <[hidden email]>:
>> 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 <[hidden email]>:
>>>>
>>>> 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
>>>> [hidden email]
>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>>>
>
_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Reply | Threaded
Open this post in threaded view
|

Re: Remote GHCi

Manuel M T Chakravarty-4
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 <[hidden email]>:
>
> 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 <[hidden email]>:
>>> 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 <[hidden email]>:
>>>>>
>>>>> 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
>>>>> [hidden email]
>>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>>>>
>>
> _______________________________________________
> ghc-devs mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Reply | Threaded
Open this post in threaded view
|

Re: Remote GHCi

Alan & Kim Zimmerman
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 <[hidden email]> 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 <[hidden email]>:
>
> 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 <[hidden email]>:
>>> 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 <[hidden email]>:
>>>>>
>>>>> 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
>>>>> [hidden email]
>>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>>>>
>>
> _______________________________________________
> ghc-devs mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Reply | Threaded
Open this post in threaded view
|

Re: Remote GHCi

Simon Marlow-7
In reply to this post by Manuel M T Chakravarty-4
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 <[hidden email]>:
>>
>> 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 <[hidden email]>:
>>>> 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 <[hidden email]>:
>>>>>>
>>>>>> 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
>>>>>> [hidden email]
>>>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>>>>>
>>>
>> _______________________________________________
>> ghc-devs mailing list
>> [hidden email]
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>
_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Reply | Threaded
Open this post in threaded view
|

Re: Remote GHCi

Simon Marlow-7
In reply to this post by Alan & Kim Zimmerman
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
> <[hidden email] <mailto:[hidden email]>> 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 <[hidden email] <mailto:[hidden email]>>:
>      >
>      > 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 <[hidden email] <mailto:[hidden email]>>:
>      >>> 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 <[hidden email] <mailto:[hidden email]>>:
>      >>>>>
>      >>>>> 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
>      >>>>> [hidden email] <mailto:[hidden email]>
>      >>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>      >>>>
>      >>
>      > _______________________________________________
>      > ghc-devs mailing list
>      > [hidden email] <mailto:[hidden email]>
>      > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>
>     _______________________________________________
>     ghc-devs mailing list
>     [hidden email] <mailto:[hidden email]>
>     http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>
>
_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Reply | Threaded
Open this post in threaded view
|

Re: Remote GHCi

Edward Z. Yang
In reply to this post by Simon Marlow-7
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
_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Reply | Threaded
Open this post in threaded view
|

Re: Remote GHCi

Moritz Angermann
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 <[hidden email]> 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

_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Reply | Threaded
Open this post in threaded view
|

Re: Remote GHCi

Simon Marlow-7
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 <[hidden email]> 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
>
_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
12