content: \begin{comment}
  \begin{code}
  {-# LANGUAGE RecordWildCards #-}
  
  module LiveCoding.Preliminary.LiveProgram.HotCodeSwap where
  
  -- base
  import Control.Concurrent
  import Control.Monad (forever)
  
  -- essence-of-live-coding
  import LiveCoding.Preliminary.LiveProgram.LiveProgramPreliminary
  \end{code}
  \end{comment}
  
  \begin{figure}
  \begin{code}
  hotCodeSwap
    :: (s -> s')
    -> LiveProgram m s'
    -> LiveProgram m s
    -> LiveProgram m s'
  hotCodeSwap migrate newProgram oldProgram
    = LiveProgram
      { liveState = migrate $ liveState oldProgram
      , liveStep  = liveStep newProgram
      }
  \end{code}
  \caption{\texttt{Preliminary/HotCodeSwap.lhs}}
  \label{fig:hot code swap}
  \end{figure}
  \fxwarning{The thing with the MVar doesn't work on the spot anymore. But it can still work with a "typed" handle. Every time you swap, you get a new handle that carries the currently saved type. Worth commenting upon?
  It's somewhat complicated: We have to kill the old MVar and create a new one every time we update. Then we also have to update the ticking function}
  \begin{comment}
  \begin{code}
  type LiveRef s = (MVar (LiveProgram IO s), MVar (IO ()))
  launch :: LiveProgram IO s -> IO (LiveRef s)
  launch liveProg = do
    progVar <- newMVar liveProg
    tickVar <- newMVar $ tick progVar
    forkIO $ forever $ do
      action <- takeMVar tickVar
      action
      tryPutMVar tickVar action
    return (progVar, tickVar)
  
  tick :: MVar (LiveProgram IO s) -> IO ()
  tick var = do
    LiveProgram {..} <- takeMVar var
    liveState' <- liveStep liveState
    putMVar var LiveProgram { liveState = liveState', .. }
  
  swapWith :: (s -> s') -> LiveProgram IO s' -> LiveRef s -> IO (LiveRef s')
  swapWith migrate (LiveProgram _newState newStep) (progVar, actionVar) = do
    _ <- takeMVar actionVar
    LiveProgram oldState oldStep <- takeMVar progVar
    let newProg = LiveProgram (migrate oldState) newStep
    newProgVar <- newMVar newProg
    putMVar actionVar $ tick newProgVar
    return (newProgVar, actionVar)
  \end{code}
  \end{comment}
  