Suppose I have a function that performs an place transformation on the first variable
function f!(x,y)
# code here
x
end
This function can result in an error, so I would like to return a flag, variable, alerting me if there was a problem. Should the code now have a return? If it has a return, should it not be named with a !? As a simple example, consider:
function f!(x, y)
flag = 0;
for j in 1:length(x)
x[j]-=y;
end
if(sum(x)<0)
flag = -1;
end
x
return flag
end
There’s no difference to ending a function with a or return a (see the docs here). The convention with ! is that a function ending with ! modifies the first argument itself, e.g. set_first_to_1!(v::Vector) = v[1]=1 which is a function that mutates v by setting its first entry to 1.
As a matter of style and simplicity, rather than returning an error code or an error value or setting an auxiliary error variable – and the error is not something that is recoverable – throw(<some type of exception>) instead. That keeps function call results useful for additional calculation immediately.
the ! is a style convention to indicate that the function modifies its argument(s),
some of these function also return this argument, making code like
f!(x, y, z) = (...; x) # x is the value
f(y, z) = f!(allocate_new_x(y, z), y, z)
easy to write.
From your example, we don’t know if this is relevant for your context. If yes (ie you want an in-place and a functional version), then I would return (x, flag).