fixes #174 -- minimize calls to discardChanges for if/bind/repeat

inspired by #176, this accomplishes a similar ends. The main difference is instead of using CompoundObserver.value_ directly, we thread through the value of if/bind/repeat that we got from `open`. It also ensures that if if/bind/repeat changes, we still use discardChanges to get the updated value of the other one.

Verified that the test failed on the original version -- it was calling discardChanges() for the "bound" and "predicate" observers 3 to 4 times, now it's once each.

I'm not super happy with the method names -- suggestions appreciated. Tried to follow the original style, which seemed to be avoiding closures inside of `updateDependencies`.