Expression caching

improved version of #9006 (which was an improved version of #8942)