A function cannot affect its caller's positional parameters. This is by design: positional parameters are meant to be private to the function.

Make your function work on an array.

    myfunction () {
      local _myfunction_arrayname=$1
      shift
      … # work on the positional parameters
      eval "$_myfunction_arrayname=(\"\$@\")"
    }
    myfunction foo "$@"
    set -- "${foo[@]}"


In ksh93 and bash, there's a roundabout way to do something approaching by combining an alias and the `.` (`source`) builtin with a process substitution. [Example](https://unix.stackexchange.com/questions/320598/how-can-i-choose-one-of-locates-results-and-let-it-be-opened-with-a-specified/320707#320707).

    alias myfunction='. <(echo myfunction_body \"\$@\"; echo set -- "\"\${new_positional_parameters[@]}\"")'

Put the meat of the work of the function in `myfunction_body` and make it set the array `new_positional_parameters`. After a call to `myfunction`, the positional parameters are set to the values that `myfunction_body` puts in `new_positional_parameters`.