diff --git a/README.md b/README.md index a0786ec..5f86f6a 100644 --- a/README.md +++ b/README.md @@ -48,4 +48,8 @@ Contributions are very welcome, as are feature requests and suggestions. Please ## Documentation -Nulls.jl is a very simple package: it provides a single type `Null` with a single instance `null`. It also defines basic operators on `null` so that it essentially becomes a `NaN` for any type. e.g. `null < 1 == false` and `null == 1 == false`. It is also not dissimilar to the type `Void` with single instance `nothing` in Julia. The difference is where `nothing` is used as, for example, the return type of `print`, `null` has more operations defined and conceptually is used to represent missing values in data. +Nulls.jl provides a single type `Null` with a single instance `null` which represents a missing value in data. `null` values behave essentially like [`NULL` in SQL](https://en.wikipedia.org/wiki/Null_(SQL)) or [`NA` in R](https://cran.r-project.org/doc/manuals/r-release/R-lang.html#NA-handling). `null` differs from `nothing` (the object returned by Julia functions and blocks which do not return any value) in that it can be passed to many operators and functions, prompting them to return `null`. Where appropriate, packages should provide methods propagating `null` for the functions they define. + +The package defines standard operators and functions which propagate `null` values: for example `1 + null` and `cos(null)` both return `null`. In particular, note that comparison operators `==`, `<`, `>`, `<=` and `=>` (but not `isequal` nor `isless`) also propagate `null`, so that `1 == null` and `null == null` both return `null`. Use `isnull` to test whether a value is `null`. Logical operators `&`, `|`, `⊻`/`xor` implement [three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic): they return `null` only when the result cannot be determined. For example, `true & null` returns `null` but `true | null` returns `true`. + +In many cases, `null` values will have to be skipped or replaced with a valid value. For example, `sum([1, null])` returns `null` due to the behavior of `+`. Use `sum(Nulls.skip([1, null])` to ignore `null` values. `sum(Nulls.replace([1, null], 0))` would have the same effect. `Nulls.fail` throws an error if any value is found while iterating over the data. These three functions return an iterator and therefore do not need to allocate a copy of the data. Finally, the `Nulls.coalesce` function is a more complex and powerful version of `Nulls.replace`.