Bear in mind that functions should only be as complicated as necessary. Instead of taking a data.frame and column names, then looking for those columns in the data, just ask for the vectors.
vector_function <- function(var1, var2){
var1 + var2
}
df.augmented <- df.out %>%
mutate(z = vector_function(x, y))
Non-standard evaluation is only necessary for extremely general functions. And even then, a vector-input function is often the better choice in keeping things general. With the example above, df.function would overwrite any existing z column, while vector_function allows the user to specify the column name.
Sometimes, narrowly focused functions could benefit from NSE if they exploit the fact that it's not evaluated. For example, the dbplyr package allows statements to be executed in a database instead of R because it catches arguments before evaluation.
Unless there's a benefit to using NSE, see if you can make the function vector-based. They're simpler to write, debug, understand, and use inside other functions.