An Elixir convention I've seen is to put the thing you're operating on first, so that you can compose functions using the `|>` operator, which places the previous expression as the first argument of the function to the right.
Maybe something like this?
defmodule Compare do
def clamp(number, minimum, maximum) do
number
|> max(minimum)
|> min(maximum)
end
end
import Compare
clamp(5, 1, 10) # 5
clamp(1, 5, 10) # 5
clamp(10, 1, 5) # 5
some_number
|> clamp(min, max)
As a side note, I think the Elixir |> operator is a stroke of genius that other languages should take a look at. Making the pipe operator append the _first_ argument has the following benefits
1.) It makes the most "important" argument of the function the first thing you read in function signatures
2.) If you need to add more arguments to a function signature later, they tend to be less important the original args, so they tend to make sense at the end
3.) It creates a convention for all libraries to follow so they can leverage the pipe operator. Its really jarring when the thing you want to put in a pipeline isn't the first argument (looking at you `Regex`[0] which puts the regular expression as the first arg and not the string)
> It makes the most "important" argument of the function the first thing you read in function signatures
Doesn't that make writing functions that can use partial application harder? e.g. If I was writing clamp i would want the signature to be
(defn clamp [min max n] ,,,)
Then I can do:
(map (partial clamp 1 11) [-14 2 5 8 11 15 18])
I know when I use Clojures threading macros I use thread last way more than any of the others. My next most common would be piping it into arbitrary locations, e.g.:
; pipe into an arbitrary spot (specified here as o)
(as-> (range 1 10) o
(map inc o)
(filter even? o)
(reduce + o))
defmodule Math do
def clamp(num, _min, max) when num > max, do: max
def clamp(num, min, _max) when num < min, do: min
def clamp(num, _min, _max), do: num
end
Following xxs example of looking at NaN behavior, with this code, a bound (say lower) of NaN means that bound is disabled. Which may or may not be what you want.