[darcs-devel] darcs patch: rewrite ColourPrinter with a policy data type (fixes R...

David Roundy droundy at abridgegame.org
Mon Apr 4 06:19:28 PDT 2005


On Mon, Apr 04, 2005 at 03:02:30PM +0200, Tommy Pettersson wrote:
> On Mon, Apr 04, 2005 at 08:35:59AM -0400, David Roundy wrote:
> > > +-- printers
> > > +
> > > +fancyPrinters :: IO (Printers)
> > > +fancyPrinters =
> > > + do po <- getPolicy
> > > +    return Printers { colorP     = colorPrinter po,
> > > +                      invisibleP = invisiblePrinter,
> > > +                      defP       = escapePrinter po
> > > +                    }
> > 
> > Here we could use unsafePerformIO to avoid calling getPolicy many times,
> > which would also move fancyPrinters out of the IO monad.  It's a tad ugly,
> > but would have the (probably totally unimportant) advantage of saving one
> > call to isTerminal and one to getTermNColors per patch printed.
> 
> Ah, of course.  The synchronous IO will happen on each call.  That was
> not my intention.  I was afraid that the curses library could be
> uninitialized at the time of unsafePerformIO so that getTermNColors could
> fail.  Can that happen?

I don't believe so.  Note that the unsafePerformIO'ed function still won't
get called until its result is needed (due to lazy evaluation).  And I
don't think there is a restriction on when getTermNColors can be called
anyways.

> > Note that we could also put an unsafePerformIO in getPolicy, which would
> > move both getPolicy and fancyPrinters out of the IO monad (at the cost of
> > some ugliness).  Note that if you used this trick, you'd probably also want
> > to (or have to?) add a NOINLINE pragma.
> 
> I don't know what NOINLINE is.  Where can I read about it.

Hmmm.  Somewhere in the ghc manual...  Or you could grep the darcs sources
if you just want to see its syntax.  It just tells ghc not to inline a
function, and can be used together with unsafePerformIO as a hack to cause
an IO function to be called once and only once.  One shouldn't depend on it
only being called once, and there's no reliable way to know *when* it will
be called, but for things like that shouldn't ever change (checking
environment variables, or in this case whether stdout is a terminal) it's
safe (in spite of the name).  But it's still ugly.
-- 
David Roundy




More information about the darcs-devel mailing list