Internal and external interpreter differ in interaction between putQ and recover
Take the following sample program. This places a value of "0" into the TH state. Then within a recover block it places a value of "42" there, and then immediately errors.
We then lift whatever the current value in the store is.
{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.TH.Syntax
main = print $(putQ "0" >> recover (pure ()) (putQ "42" >> fail "oops") >> getQ @String >>= lift )
There are two reasonable answers to what this program should print.
It will print 0 if we roll back state when we recover from an error (This is how the external interpreter handles it). We will print 42 if we do not rollback state (this is how the internal interpreter handles it`
We get different answers whether we run with the internal or external interpreter.
ghc on wip/abstract-q [$!?] via λ 9.10.1 via via ❄️ impure (ghc-shell-for-ghc-buildenv-9.13-0-env)
❯ ghc Test.hs -fforce-recomp -fexternal-interpreter && ./Test
[1 of 2] Compiling Main ( Test.hs, Test.o )
[2 of 2] Linking Test [Objects changed]
Just "0"
ghc on wip/abstract-q [$!?] via λ 9.10.1 via via ❄️ impure (ghc-shell-for-ghc-buildenv-9.13-0-env)
❯ ghc Test.hs -fforce-recomp && ./Test
[1 of 2] Compiling Main ( Test.hs, Test.o )
[2 of 2] Linking Test [Objects changed]
Just "42"
We should pick one of these semantics and stick with it!