Hotswap
Hotswap is a simple, high level interface to plugins for hotswapping Haskell code in a simple and automatable manner.
Demo application: gambling.
Main.hs
import Control.Monad
import System.Plugins.Hotswap
import System.IO (hSetBuffering, stdout, BufferMode (NoBuffering))
main :: IO ()
= do
main NoBuffering
hSetBuffering stdout <- newPlugin "Plugin.o" [] "inputHandler" :: IO (Plugin (IO Bool))
inputHandler $ do
forever <- runPlugin inputHandler
r $ reloadPlugin inputHandler when r
Plugin.hs
module Plugin where
import System.Random (randomRIO)
inputHandler :: IO Bool
= do
inputHandler putStrLn "Guess a number between 0 and 10. Guess -1 to reload the plugin."
<- fmap read getLine :: IO Int
g
if g == -1
then do
putStrLn "Reloading ..."
return True
else do
<- randomRIO (0, 10) :: IO Int
r if g == r
then putStrLn "Congratulations! You win nothing!"
else putStrLn "Wrong! You lose nothing, but bring shame to your people."
return False
Then, to compile and run this, I run in a shell:
~/code/projects/hotswap/examples> ghc --make -O2 -threaded Main
[1 of 1] Compiling Main ( Main.hs, Main.o )
Linking Main ...
~/code/projects/hotswap/examples> ghc Plugin
[1 of 1] Compiling Plugin ( Plugin.hs, Plugin.o )
~/code/projects/hotswap/examples> ./Main # example run:
Guess a number between 0 and 10. Guess -1 to reload the plugin.
5
Wrong! You lose nothing, but bring shame to your people.
Guess a number between 0 and 10. Guess -1 to reload the plugin.
4
Congratulations! You win nothing!
Guess a number between 0 and 10. Guess -1 to reload the plugin.
3
Wrong! You lose nothing, but bring shame to your people.
Guess a number between 0 and 10. Guess -1 to reload the plugin.
5
Wrong! You lose nothing, but bring shame to your people.
Guess a number between 0 and 10. Guess -1 to reload the plugin.
6
Wrong! You lose nothing, but bring shame to your people.
Guess a number between 0 and 10. Guess -1 to reload the plugin.
1
Wrong! You lose nothing, but bring shame to your people.
Guess a number between 0 and 10. Guess -1 to reload the plugin.
-1
Reloading ...
Guess a number between 0 and 10. Guess -1 to reload the plugin.
^Z
zsh: suspended ./Main
Pretty mundane. But, lets say I want to change what happens when you guess incorrectly.
~/code/projects/hotswap/examples> sed -i -e "s/else putStrLn.*/else putStrLn \"HAHA, YOU'RE HORRIBLE\"/g" Plugin.hs
~/code/projects/hotswap/examples> ghc Plugin
[1 of 1] Compiling Plugin ( Plugin.hs, Plugin.o )
~/code/projects/hotswap/examples> fg
[1] + continued ./Main
5
Wrong! You lose nothing, but bring shame to your people.
Guess a number between 0 and 10. Guess -1 to reload the plugin.
-1
Reloading ...
Guess a number between 0 and 10. Guess -1 to reload the plugin.
4
HAHA, YOU'RE HORRIBLE
Guess a number between 0 and 10. Guess -1 to reload the plugin.
And there we have it, hotswapping!
Todo
- Entirely automatic hotswapping:
- Specify a source file; it gets compiled for you, and is watched for changes
- A good, cross platform and fast file watching library.
- More examples!