Day 88: A shiny new monad.

autrijus on 2005-04-29T18:40:34

After much help from TheHunter and skew in #haskell, I have finished the new definition of Pugs's main Eval monad. Curiously, it uses all four structure declaration statements in Haskell:

type Eval x = EvalT (ContT Val (ReaderT Env SIO)) x
newtype EvalT m a = EvalT { runEvalT :: m a }
data SIO a = MkSTM (STM a) | MkIO (IO a) | MkSIO a
class (MonadReader Env m, MonadCont m, MonadIO m, MonadSTM m) => MonadEval m

As yesterday's journal indicated, the key idea behind this restructuring is that we can safely use both liftSTM (for in-memory variable access) and liftIO (for input/output with the external world) primitives, and mix them freely in a normal runIO evaluator:

runIO :: SIO a -> IO a
runIO (MkIO io)     = io
runIO (MkSTM stm)   = atomically stm
runIO (MkSIO x)     = return x
However, inside a atomic {} block, runSTM is used instead, so atomic { say "Hello" } will trigger an exception:
runSTM :: SIO a -> STM a
runSTM (MkSTM stm)  = stm
runSTM (MkIO _ )    = fail "Unsafe IO caught in STM"
runSTM (MkSIO x)    = return x
Although I had not got around to expose the atomic primitive, the restructured SIO structure has already improved performance dramatically (again):
 autrijus?
 What the hell changed in the last 12 hours with pugs?
 hi. schwern made all our :todo fail.
 or rather, all the force_todo fail
 so you should see red.
 don't panic :)
 "env PUGS_RELEASE=1 make smoke"
 will give the original green one.
 no. I mean it smoked 30% faster
 obra: oh. yeah. I rewrote the monad

Another big news today is I have largely rewritten the Statements structure and associated Exp types; each token in the parse stream is now assigned ranges, for a much better diagnostics output:

$ ./pugs -e 'die "Hello, World!"'
*** Error: Hello, World! at -e line 1, column 1-20
Note the column range above; multi-line constructs are also handled correctly. Much thanks to gaal for keep prodding me with his #line patch, and for reporting various breakage in the old, statement-level position handling scheme.

In other news, Larry invoked a Rule 2 today on S02: during array/hash slicing, outside context is now no longer propagated to index expressions. This resolves the problem encountered by Juerd and me a few days ago; Pugs has been fixed to adopt the new semantic.

As the IRC log above indicated, Schwern fixed our Test.pm so force_todo failures are still reported as failures during normal development. To inhibit them, one must set the PUGS_RELEASE environment variable to a true value. Stevan is still working toward a better way to replace force_todo, perhaps based on a multi-level todo notation like :todo<bug> and :todo<feature>...

theorbtwo valiantly hacked forward on adding Haddock support to Pugs, but kept running into Haddock limitations against newer GHC features (e.g. GADTs). The current plan is to write a simple translator to convert our .hs files to Haddock-complaint .hpp files, while minimizing the information loss.

Aside from hacking on #line support, gaal ported Pugs to Cygwin, although the .msi version of GHC is still needed.

Corion and iblech unTODOed and cleaned up various tests as usual; bsb reported that the current CVS version of GHC 6.5 already contained the same copy of Unicode.hs as our own, causing conflicting symbols. This is now fixed.

That's it for today. See you tomorrow!


hehe

Qiang on 2005-04-29T21:05:10

"Sorry for the short answers, but I'm in Russia behind a flakey network connection, which is probably going away entirely at any moment (the network connection, not Russia.)"

I had a chuckle on that one. hehe