[NN primitives] unify var parameters vs return values
The library is inconsistent in nn_primitives for when to use return values and when to use var parameters that will be updated in place.

### var parameter
https://github.com/mratsim/Arraymancer/blob/92aa82e8c7d2a30c4497d5cf367c89f30c648a68/src/nn_primitives/nnp_linear.nim#L20-L28

https://github.com/mratsim/Arraymancer/blob/92aa82e8c7d2a30c4497d5cf367c89f30c648a68/src/nn_primitives/fallback/conv.nim#L19-L20

https://github.com/mratsim/Arraymancer/blob/92aa82e8c7d2a30c4497d5cf367c89f30c648a68/src/nn_primitives/nnp_convolution.nim#L65-L70

### return value

https://github.com/mratsim/Arraymancer/blob/92aa82e8c7d2a30c4497d5cf367c89f30c648a68/src/nn_primitives/fallback/conv.nim#L57-L59

https://github.com/mratsim/Arraymancer/blob/92aa82e8c7d2a30c4497d5cf367c89f30c648a68/src/nn_primitives/nnp_convolution.nim#L28-L31

## Possibilities

1. Always use `var`
    - 👍 Makes sure there is no extra allocation
    - 👍 Consistency
    - 👎 Must declare result before calling function (and computes the shape for `im2col` for example)
    - 👎 No chaining

2. Always use return values
    - 👍 Consistency
    - 👍 No call burden
    - 🔢 Sometimes return value is a tuple (i.e. forces to read doc for unwrapping)
           - Can be alleviated with named tuple parameters
           - If tuple, it's not easy to chain functions (but is it needed for nn_primitives?)

3. Return value if single, `var` parameters otherwise?
    - 👎 Inconsistent
    - The worst of both worlds?
