Introduce distance() and unify some API

Original work by Lucas.

No functional change.