
H Twan,
While I was in a masochistic mood this week, I decided to change Yhc to use proper monads.
Something that was definately in need of doing, and I'm impressed you managed it!
I have replaced this mess by usage of the mtl, in particular Control.Monad.State and Control.Monad.Writer. Usage of (>>>=) is replaced by do notation. As replacement for the (=>>>) operator I use (<*>) and (<$>) based on Control.Applicative.
All very sensible.
Most functions are generalized over this class. And to further improve the readability, all state and environment types are now records.
Woohoo! Records was something that was definately required!
Now, I may have introduced some bugs. The code was rather fond of Yhc does still pass the test suite.
Thats enough for me, if it doesn't work now, thats a bug in our test suite.
I may have also removed some of the strictness, in the old code =>>> (aka. <*>) was strict in the state, after the cleanup it no longer is. This could be fixed by using a different monad. There is already a StrictState monad in State.hs which I used for debugging (to get traces in some sensible order).
I know the old compiler was carefully optimised for memory useage, but I'd say that clearer code wins, and I'm not convinced it was still memory efficient. Changing the strictness slightly to get better code is sensible.
Unfortunately, the code now requires -fglasgow-exts (or a LANGUAGE pragma) in some places. The only reason for this is FlexibleInstances for the instance:
instance MonadIS (State IntState) where ... If this is a problem it might be possible to work around it by changing it to: class HasIntState a instance HasIntState a => MonadIS (State a) But IMO FlexibleInstances are a noncontroversial extension, and they are supported by most compilers.
Alas but not Yhc - which will break our goal of being self-compiling at some stage. How much work is it to move to not requiring this? If that could be done, then this patch will definately be applied.
Finally, it should be noted that I kind of gave up at the end; the type checker just uses runState to get around the monads. The reason for this is that I saw a circular reference there somewhere, and I decided it was best not to mess with it.
Fair enough, I'm impressed you got as far as you did. Thanks Neil