a) No. In the new-style function format (using staticmethods and ctx) you can give arbitrary arguments to functions
b) Variables (but only those given directly, those in lists won’t be unwrapped) are unwrapped, all other arguments are passes as they are. forward() works only on tensors and should only return tensors. backward() works only on Variables and should return only Variables.
c) I don’t think I understand the question
d) backward() works with Variables so that it can be differentiated itself (for higher order derivatives). You can always use the @once_differentiable decorator to make it unwrap tensors, but raise an error if you try to differentiate twice.
I don’t think we have any code specific to tensor types.
The convention is Function.apply(*args).
Hope this helps