add memoize expiration

This allows memoized functions to have an expiration time (expressed in milliseconds). In general this is backward compatible, because the expire parameter is after the hasher and is optional (falsey values are infinite). 

One issue is that you seem to expect (from your test code at least) that callers might want to directly manipulate the cache, e.g. fn. memo['foo'] = ['bar']. This would no longer be valid as the value stored at fn. memo['foo'] would be an object of the form {result: ['bar'], ts: new Date().getTime()}. 

If you feel that particular use case must be supported, I can provide a less direct implementation, e.g. fn.memo remanins unchanged and there is a different property fn.memo_ts which is the map of timestamps used for expiration.