Lazy evaluation

Not ready for merge, just here for comments.

Based on #580.