It’s intended. I think some frameworks use one definition, while others use the second one.
In-place operations are not encouraged if they don’t have to be used, but you have to use them in the optimizer, because you want to actually modify the parameters of the model. You don’t have access to the original module/container/whatever object is holding the parameters, so p = p - self.lr * dp wouldn’t work, because you can’t reassign the p in the object that holds it.