You can call a function transparently within a mapping, thus circumventing
mode changes (e.g. by pressing :
) or losing counts, by using <expr>
mappings, similar to what you suggested. Just use them to call a function like so:
funfunction! SetOpFunc()
set opfunc=CountSpaces
return 'g@'
endfun
nnonnoremap <expr> <F4> SetOpFunc()
This technique isn't limited to operator mappings either. For example
I've used it in Operator-pending mappings to call a function during the
mapping without disrupting modes or counts, returning ''
at the end.
This way you can leverage Vim's native features rather than having to
recreate them yourself.