← Code Compare

Sorting

Two sorts in all five BEAM languages: the trivial [3, 1, 2] -> [1, 2, 3], then a list of {name, age} people sorted by age descending. Watch the two flavours of API - Erlang and LFE pass a comparator fun(A, B) -> A > B to lists:sort/2, Elixir and Gleam prefer a key function (Enum.sort_by / list.sort with a by: comparator) so you say what to sort on rather than how to compare, and Luerl falls back to Lua's in-place table.sort with a <-style comparator closure.

Show: ErlangElixirGleamLFELuerl
Erlang
-module(sorting).
-export([run/0]).

run() ->
    Sorted = lists:sort([3, 1, 2]),
    %% => [1, 2, 3]

    People = [{"Alice", 30}, {"Bob", 25}, {"Carol", 35}],
    %% lists:sort/2 takes a comparator returning true when A should come first.
    %% Sort by age descending: A precedes B when A's age is greater.
    ByAgeDesc = lists:sort(
        fun({_, AgeA}, {_, AgeB}) -> AgeA >= AgeB end,
        People),
    %% => [{"Carol",35}, {"Alice",30}, {"Bob",25}]

    {Sorted, ByAgeDesc}.

Erlang's lists:sort/1 handles the default ascending order, while lists:sort/2 takes a comparator fun that returns true when its first argument should sort before its second; the {_, AgeA} patterns pull the age straight out of each tuple.

Elixir
people = [%{name: "Alice", age: 30}, %{name: "Bob", age: 25}, %{name: "Carol", age: 35}]

sorted = Enum.sort([3, 1, 2])
# => [1, 2, 3]

# Enum.sort_by takes a *key function*; :desc says biggest key first.
by_age_desc = Enum.sort_by(people, & &1.age, :desc)
# => [%{name: "Carol", age: 35},
#     %{name: "Alice", age: 30},
#     %{name: "Bob",   age: 25}]

{sorted, by_age_desc}

Elixir favours Enum.sort_by/3: you give a key function (& &1.age, the capture shorthand for fn p -> p.age end) and a direction atom like :desc, so you describe what to sort on instead of writing a comparator by hand.

Gleam
import gleam/int
import gleam/io
import gleam/list
import gleam/order.{type Order}
import gleam/string

pub type Person {
  Person(name: String, age: Int)
}

pub fn main() {
  let sorted = list.sort([3, 1, 2], by: int.compare)
  // => [1, 2, 3]

  let people = [
    Person("Alice", 30),
    Person("Bob", 25),
    Person("Carol", 35),
  ]

  // list.sort takes a comparator returning an Order (Lt/Eq/Gt).
  // Flip the arguments to int.compare to sort ages descending.
  let by_age_desc =
    list.sort(people, by: fn(a: Person, b: Person) -> Order {
      int.compare(b.age, a.age)
    })
  // => [Person("Carol", 35), Person("Alice", 30), Person("Bob", 25)]

  io.println(string.inspect(sorted))
  io.println(string.inspect(by_age_desc))
}

Gleam's list.sort takes a labelled by: comparator that must return an Order (Lt/Eq/Gt), and int.compare builds one for you; swapping its arguments (int.compare(b.age, a.age)) flips ascending into descending without any mutation.

LFE
(defmodule sorting
  (export (run 0)))

(defun run ()
  (let ((sorted (lists:sort '(3 1 2)))
        ;; => (1 2 3)
        (people (list (tuple "Alice" 30)
                      (tuple "Bob" 25)
                      (tuple "Carol" 35))))
    ;; lists:sort/2 takes a comparator; return 'true when A sorts first.
    ;; Match the age out of each tuple and compare descending with >=.
    (let ((by-age-desc
           (lists:sort
             (lambda (a b)
               (>= (element 2 a) (element 2 b)))
             people)))
      ;; => (#("Carol" 35) #("Alice" 30) #("Bob" 25))
      (tuple sorted by-age-desc))))

LFE calls the same Erlang lists:sort/1 and lists:sort/2, written as S-expressions: the comparator is a (lambda (a b) ...) that pulls each age with (element 2 a) and returns true for descending order via (>= ...).

Luerl
local nums = {3, 1, 2}

-- table.sort mutates the table in place; no comparator = ascending.
table.sort(nums)
-- nums is now {1, 2, 3}

local people = {
  { name = "Alice", age = 30 },
  { name = "Bob",   age = 25 },
  { name = "Carol", age = 35 },
}

-- The comparator returns true when a should come before b.
-- a.age > b.age gives descending order by age.
table.sort(people, function(a, b)
  return a.age > b.age
end)
-- people is now ordered Carol (35), Alice (30), Bob (25)

for _, p in ipairs(people) do
  print(p.name, p.age)
end

Standard Lua (what Luerl runs) sorts a table in place with table.sort; the optional second argument is a comparator closure returning true when its first argument sorts first, so a.age > b.age yields a descending order.