# Design
This document outlines the design guide lines of this module.
This module is composed by independent operations common in analytics. Below are some design of its
principles:
- APIs MUST return an error when either:
- The arguments are incorrect
- The execution results in a predictable error (e.g. divide by zero)
- APIs MAY error when an operation overflows (e.g. `i32 + i32`)
- kernels MUST NOT have side-effects
- kernels MUST NOT take ownership of any of its arguments (i.e. everything must be a reference).
- APIs SHOULD error when an operation on variable sized containers can overflow the maximum size of
`usize`.
- Kernels SHOULD use the arrays' logical type to decide whether kernels can be applied on an array.
For example, `Date32 + Date32` is meaningless and SHOULD NOT be implemented.
- Kernels SHOULD be implemented via `clone`, `slice` or the `iterator` API provided by `Buffer`,
`Bitmap`, `Vec` or `MutableBitmap`.
- Kernels MUST NOT use any API to read bits other than the ones provided by `Bitmap`.
- Implementations SHOULD aim for auto-vectorization, which is usually accomplished via
`from_trusted_len_iter`.
- Implementations MUST feature-gate any implementation that requires external dependencies
- When a kernel accepts dynamically-typed arrays, it MUST expect them as `&dyn Array`.
- When an API returns `&dyn Array`, it MUST return `Box<dyn Array>`. The rational is that a `Box` is
mutable, while an `Arc` is not. As such, `Box` offers the most flexible API to consumers and the
compiler. Users can cast a `Box` into `Arc` via `.into()`.