If I understand your mapping properly it is used to get the directory containing the current buffer and then
cd to this directory.
You say that your mapping leaves characters in your current buffer and that is why you want to use a function. I think that using a function here is not necessary you just need to write a better mapping. By "better mapping" I mean a mapping which will use built-in features and will not have to modify your buffer just to change the working directory.
For example something like this would do the job:
nnoremap <yourkey> :execute "cd " . expand('%:h')<CR>
Let's break the executed command down:
execute "cd " . expand('%:h')
execute will take a string and execute it as a command
"cd " is the beginning of the command you want to execute
. allows to concatenate two strings
expand(' ') will be used to tranform a file name as we want
% is the current file name
:h tells to expand() to return only the directory of the file
You can try to use directly in the command line
:echo expand('%:h') to understand better what's happening.
Here are some help topics you might want to read:
Edit As @LuHermitte pointed out in the comments, while the previous mappings works using
expand() is clearly overkill since the command line can substitute
%:h on its own. So the mapping should be
nnoremap <silent> <yourkey> :cd %:h<CR>
<silent> to avoid echoing the mapping in the command line)