backport memoiziation from 3.0