Differentiability is a property on a function, not on parameter types. Other than its mathematical definition, it is because a differentiable function has a different layout.
Say, a normal "thin" function is a function pointer. A (reverse-mode) differentiable function is a product of these:
- The original function pointer
- The primal function pointer
- The adjoint function pointer
In most cases, a differentiable function is differentiable with respect to all parameters.
In forward-mode differentiation, a function can be differentiable from all (or a subset of) results with respect to a single parameter. In that case, even results can be selected. Swift doesn't formally model multiple results as a result list, so result selection syntax can be trickier than parameter selection.
A full-blown version of parameter/result selection can look like the following, but it's kind of off-topic.
// f(x0, x1, x2) = (y0, y1, y2)
let f: @differentiable (T0, @nodiff T1, T2) -> (@nodiff U0, U1, U2)
// Jacobian
#jacobian(f)(x0, x1, x2) // ((∂y1/∂x0, ∂y1/∂x2), (∂y2/∂x0, ∂y2/∂x2))
// Forward-mode differentiation
#derivatives(f, wrt: .0)(x0, x1, x2) // (∂y1/∂x0, ∂y2/∂x0)
#derivatives(f, wrt: .1)(x0, x1, x2) // error: parameter #1 is not differentiable-with-respect-to
#derivatives(f, wrt: .2)(x0, x1, x2) // (∂y1/∂x2, ∂y2/∂x2)