Skip to content

sabiwara/cmp

Repository files navigation

Cmp

Hex Version docs CI

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]
false

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> Date.compare(~D[2019-01-01], ~D[2020-03-02])
:lt

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 does the right thing out of the box:

iex> Cmp.gt?(~D[2020-03-02], ~D[2019-06-06])
true

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-in comparators accept any set of operands:

iex> 2 < "1"
true

iex> 0 < true
true

iex> false < nil
true

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

iex> Cmp.lte?(1, 1.0)
true

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 mix.exs:

def deps do
  [
    {:cmp, "~> 0.1.3"}
  ]
end

The documentation can be found at https://hexdocs.pm/cmp.

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)

Supporting comparisons between non-homogeneous types such as mixed Decimal and built-in numbers for instance is a non-goal. This limitation is a necessary trade-off in order to ensure the points above. Use the Decimal library directly if you need this.

Copyright and License

Cmp is licensed under the MIT License.

About

Semantic comparison and sorting for Elixir

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages