# The Pearls of Raku, Issue 8: the secrets of min (and max)

In this issue, we’ll be focusing on the built-in min function. Occasionally also on max, but the whole story is well applicable to both of them. Some of the elements can also be used with other functions.

In this issue, we’ll be focusing on the built-in `min` function. Occasionally, also on `max`, but the whole story is well applicable to both of them. Some of the elements can also be used with other functions.

## How to use `min`

This is not a trivial question, actually 🙂 Let’s take an array with some integers, both positive and negative, and find the minimum value using different forms of the call:

```my @data = 3, -2, 6, 1, 5;

say min @data;   # -2
say min(@data);  # -2
say @data.min;   # -2
say @data.min(); # -2```

As you can see, both a standalone function and a method are available.

But that’s not it. You can use a reduction operator with the `min` function in it:

`say [min] @data; # -2`

According to the definition, this is equivalent to the following chain, which you can also use (but why):

`say @data[0] min @data[1] min @data[2] min @data[3] min @data[4]; # -2`
<

## `min` of nothing

What if you apply `min` to an empty array? The result is logical but maybe not always intuitively straightforward.

```my @a;
say @a.min; # Inf```

Indeed, if you want to find a minimum element in the loop, you usually start with the first element and compare the next element with it. If you start with infinity, you do not have to make any special use of the first element to warm up the loop.

The same happens to `()`, `Empty`, `Nil`, or `Any`:

```say ().min;    # Inf
say Empty.min; # Inf
say Nil.min;   # Inf
say Any.min;   # Inf```

You can find more similar examples, but let me mention that with `max`, you get `-Inf`:

```say @a.max;    # -Inf
say ().max;    # -Inf
say Empty.max; # -Inf
say Nil.max;   # -Inf
say Any.max;   # -Inf```
<

## `min` with `by`

The `min` routine accepts the named argument `:by`, which you can use to modify the value before the function actually makes the comparison. For example, with our initial data array, let us find the absolute minimum value:

```my @data = 3, -2, 6, 1, 5;

say min(@data, :by( { abs(\$_) } )); # 1```

I added some air around the braces and parentheses for better visibility, but you can also use the `WhateverCode` block to increase it further:

`say min(@data, by => -*); # 6`

In this example, all the elements are negated and `min` serves as `max`.

N.B.! In the case of using a method, the only optional argument `&by` is a positional argument, so you can’t pass it as a named parameter. Just pass the code:

```say @data.min({abs(\$_)}); # 1
say @data.min: {abs(\$_)}; # 1

say @data.min: -*;        # 6```

* * *

Find the code of this issue on GitHub and browse for more Raku Pearls.