I'm not sure if it is relevant, but in HaRe (or rather haskell-token-utils), I use the dual-tree structure from diagrams.  This allows you to push constraints down from the top, but then build the formatting up from the bottom, and you only need to look at one level at a time. So effectively you format the leaves, then move up a level and format there, and so on.

On Tue, Oct 14, 2014 at 12:51 AM, Christopher Done <chrisdone@gmail.com> wrote:
On 11 October 2014 18:00, Oliver Charles <ollie@ocharles.org.uk> wrote:
> Yes, hindent is exponential in its pretty printing and that's exactly the
> program I'm trying to speed up ;) To be specific, hindent has `sandbox`
> which runs a printer and then lets me make decisions on what the resulting
> state might be. I'm curious if there are other approaches.

Indeed, it's slow to backtrack like that. For what it's worth, one
trick to speed that up is if the resulting state is OK, then just
`put` that state and continue with it, rather than throwing away a
rendered result. I doubled the speed of my style like that. But yeah,
it's not much consolation.

If you compare with the "Fundamental" style: that can pretty print a
60-line function I have here instantly, it takes no time, but my
"ChrisDone" style takes over 50 seconds and counting. So there's a
massive cost to this, but I haven't profiled it yet or attempted any
real optimizations yet (been too busy). Perhaps that can be next on my
todo list.

Another thing to consider is to turn off this branching of "this style
or that style" after a certain depth. Sort of "prune" the results to
be smaller. The deeper down the tree, the fewer branches it could
make, for example. I haven't tried this, but it could be nice.

Good luck! If you find a similarly expressive and faster way to do
this I'm all ears. :-)