Reactive Engine

Checklist

- [x] a working version of the reactive engine
- [x] binding outputs to client side with an example
- [x] `new_value`, `new_expression`, `new_observer`, `set_value` syntactic sugar
- [x] add environment isolation + tests
- [x] write tests for `UndefinedKey` and pending observers/expressions
- [x] remove tight coupling to `pandas` / `numpy`
- [x] add environment isolation context + tests
- [x] add suspend/resume feature for observers + tests
- [x] add md5 hasher for Python base types + numpy and pandas (`joblib`)
- [x] track potential inplace reactive value changes e.g. via list.remove(), add safe/unsafe mods
- [x] convert objects not using `getattr()` to use `__slots__`
- [x] make a number of methods and attributes of context private
- [x] add memoization/caching of expressions
- [x] get rid of `inspect.frame`
- [x] make `_check_hash_integrity()` selective
- [x] add further unit tests (particularly hash monitoring and caching)
- [x] test the case where env/value is accessed externally (caller is None)
- [x] 100% unit test coverage