# Cmp

[![Hex Version](](

Semantic comparison and sorting for Elixir.

## Why `Cmp`?

The built-in comparison operators as well as functions like `Enum.sort/2` or
`Enum.max/1` are based on Erlang's term ordering and suffer two issues, which
require attention and might lead to unexpected behaviors or bugs:

### 1. Structural comparisons

Built-ins use
[structural comparison over semantic comparison](

iex> ~D[2020-03-02] > ~D[2019-06-06]

iex> Enum.sort([~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]])
[~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]]

Semantic comparison is available but not straightforward:

iex>[2019-01-01], ~D[2020-03-02])

iex> Enum.sort([~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]], Date)
[~D[2019-01-01], ~D[2019-06-06], ~D[2020-03-02]]

`Cmp` will do the right right out of the box:

iex>[2020-03-02], ~D[2019-06-06])

iex> Cmp.sort([~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]])
[~D[2019-01-01], ~D[2019-06-06], ~D[2020-03-02]]

### 2. Weakly typed

Built-ins will accept any set of operands and happily compare them:

iex> 2 < "1"

iex> 0 < true

iex> false < nil

`Cmp` will only compare compatible elements or raise a `Cmp.TypeError`:

iex> Cmp.lte?(1, 1.0)

iex> Cmp.lte?(2, "1")
** (Cmp.TypeError) Failed to compare incompatible types - left: 2, right: "1"

## Installation

`Cmp` can be installed by adding `cmp` to your list of dependencies in

def deps do
    {:cmp, "~> 0.1.0"}

The documentation can be found at

## Design goals

- Fast and well-optimized - the overhead should be quite small over built-in
  equivalents. See the `benchmarks/` folder for more details.
- No need to require macros, plain functions
- Easily extensible through the `Cmp.Comparable` protocol
- Robust and well-tested (both unit and property-based)

## Copyright and License

Cmp is licensed under the [MIT License](