better temp names; more efficient workflow phase (Fixes #391)

Use State in WorkflowPhase, WorkflowBuilder, WorkflowOp to generate
unique temp names (__tmp0, ...). This should allow more projectOps
to be collapsed in the future, but as of this commit the resulting
structure should be unchanged.

New, handwritten "bound" phase that evaluates each expression only
once, propagating `Let`s down the tree, and applying a bottom-up
annotation to the rest. This reduces the amount of evaluation being
done by about 30x in some cases.

Implemented some missing combinators and ops for PhaseS.

*Note: * There is some awkward wrangling of `Attr`s going on here. Suggestions about how to make this cleaner are welcomed. See comments on the changes.
In general I don't like redundancies, because they tend to get out of sync. The final workflow plan contains enough information to determine which names are temporaries -- adding another case to `BsonField` just to mark what's already contained in the query plan seems like the wrong approach, both because it's sort of hacking `BsonField` and because it introduces another place for bugs (accidentally use Name or Index for a temp name, now it can't be renamed, etc.). That said, I don't think optimization at this level will be required for some time, so we can think about it for a while before making any decisions.