recursive with cache