Improved interface

When this PR is done, the following should be supported **and tested** for B-Spline bases. Optimization is not a concern here.

- [x] **Length**: `length(basis) => 5`
- [x] **Size**: `size(basis) => (5,)`
- [x] **Indexing**: `basis[i] => BSpline(...)`
- [x] **Domain**: `domain(basis) => (lft, rgt)`
- [x] **Evaluation**:
    - [x] Single point, no derivatives, no coefficients: `basis(x) => (vals, idxs)`
    - [x] Several points, no derivatives, no coefficients: `basis(xs) => [(vals, idxs)]`
    - [x] Single point, derivatives, no coefficients: `deriv(basis[, ord])(x) => (vals, idxs)`
    - [x] Several points, derivatives, no coefficients: `deriv(basis[, ord])(xs) => [(vals, idxs)]`
    - [x] Single point, no derivatives, coefficients: `basis(x, cs) => val`
    - [x] Several points, no derivatives, coefficients: `basis(xs, cs) => [val]`
    - [x] Single point, derivatives, coefficients: `deriv(basis[, ord])(x, cs) => val`
    - [x] Several points, derivatives, coefficients: `deriv(basis[, ord])(xs, cs) => [val]`

And the following for basis functions.

- [x] **Domain**: `domain(b) => (lft, rgt)`
- [x] **Evaluation**:
    - [x] Single point, no derivatives: `b(x) => (vals, idxs)`
    - [x] Several points, no derivatives: `b(xs) => [(vals, idxs)]`
    - [x] Single point, derivatives: `deriv(b[, ord])(x) => (vals, idxs)`
    - [x] Several points, derivatives: `deriv(b[, ord])(xs) => [(vals, idxs)]`

Auxiliary tools:

- [x] Interval type for domains.