Refactor recursion out of compute 

Previously we wrote lots of `compute` methods like the following:

```Python
@dispatch(Projection, DataFrame)
def compute(t, df):
    parent = compute(t.parent, df)
    return parent[list(t.columns)]
```

The traversal down the tree was baked into each method.  We extract this bit into an explicit `bottom_up` function and instead write methods like the following:

```Python
@dispatch(Projection, DataFrame)
def compute_one(t, df):
    return df[list(t.columns)]
```
It was skipped and languishing and I felt that the functionality was covered in various other unit tests. 

I don't actually recall why we ended up skipping it though.  A good alternative would be to figure out what was wrong with the test previously and then fix it.  I think I tended towards deletion because the test was very long and involved.

Should I keep it in in a skipped state?
Should I endeavor to fix whatever was wrong previously?