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 reproduces #174. The code was calling discardChanges() for the "bound" and "predicate" observers 3 to 4 times, now it's once each.