<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Feb 12, 2017 at 2:11 PM, <span dir="ltr"><<a href="mailto:amindfv@gmail.com" target="_blank">amindfv@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Dennis -- responses inline:<br>
<span class=""><br>
> El 11 feb 2017, a las 23:06, Dennis Raddle <<a href="mailto:dennis.raddle@gmail.com">dennis.raddle@gmail.com</a>> escribió:<br>
><br>
> My application needed the flexibility of writing test code and running it, or configuring its job (playback of music) through Haskell code and immediately testing the result (i.e. making sound and listening). I thought I would use GHCI, but I ran into some trouble. For one thing, my program forks a thread to do the timed control of the music, while the main thread implements a REPL-like "control loop" -- i.e. let me enter commands to influence the playback or halt it. I think this was crashing GHCI, perhaps when an interpreted script forks a thread which is still alive when control returns to the GHCI prompt. Not sure.<br>
><br>
<br>
</span>Would you mind sharing your code? GHCi should certainly not be crashing just because there was a forked background thread. I have done lots of the interaction you're describing (for music, also) and never had a problem like that.<br>
<span class=""><br></span></blockquote><div><br></div><div>Thanks for your comments. I am not very organized.. I'm using git, but I didn't tag or branch on my GHCi experiments so it will be hard to reconstruct what I did. Note that I'm using Sound.PortMidi in the forked thread, so maybe that's the issue. Also I thought about the possibility of compiling with -dynamic when I was trying to get interpreted code working with compiled code, but I never tried it and don't need to now.</div><div><br></div><div>D</div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
<br>
> Anyway here's what I did. Now the process that does real-time control of the playback is an entirely separate process. The control loop is started by me first, and depending on the command I enter, it builds the playback program with "ghc --make" and then spawns it. I send it signals from the control loop.<br>
><br>
> This turns out to be great. I can make changes anywhere in my playback application, from the deepest utility library to the top-level configuration script, and it builds as needed before running.<br>
><br>
> And, in the case it doesn't need to build anything, "ghc --make" finishes quickly so it doesn't feel inefficient to invoke it after every command I enter in the control loop.<br>
><br>
<br>
</span>This seems like a great solution, the only downside being that you can't directly share memory between the processes. If you'd like to do that, I recommend (careful use of!) the "foreign-store" library, which allows you to regain references you stored before a ":r" in ghci.<br>
<br>
Tom<br>
<br>
<br>
> D<br>
><br>
> ______________________________<wbr>_________________<br>
> Haskell-Cafe mailing list<br>
> To (un)subscribe, modify options or view archives go to:<br>
> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/haskell-<wbr>cafe</a><br>
> Only members subscribed via the mailman list are allowed to post.<br>
</blockquote></div><br></div></div>