first argument is self