山里は冬ぞ寂しさまさりける人目も草もかれぬと思へば
Advent Calendar 2022 78日目1の記事です。
I'm looking forward to 12/25,2022
私のAdvent Calendar 2022 一覧。
はじめに
Elixirを楽しんでいますか
&>=/2
, &<=/2
, &</2
などは、Function capturingです。
という話を書きます。
&>=/2
, &<=/2
, &</2
&>=/2
, &<=/2
, &</2
はそれぞれ、enumerableなものから最大値、最小値を取得する関数の第3引数sorter
のデフォルト値に指定されています。
第3引数sorter のデフォルト |
関数 |
---|---|
&>=/2 |
Enum.max/3 |
&>=/2 |
Enum.max_by/4 |
&<=/2 |
Enum.min/3 |
&<=/2 |
Enum.min_by/4 |
&</2 |
Enum.min_max_by/4 |
たとえば、Enum.max/3をみてみましょう。
一見するとわかりにくいかもしれません。
引数をそれぞれ詳しくみていきます。
- 第1引数
enumerable
- 第2引数
sorter
: デフォルト値は、&>=/2
※意味は後述 - 第3引数
empty_fallback
: デフォルト値は、fn -> raise Enum.EmptyError end
という引数0個の無名関数
とみます。
な〜んてことない人は、相当なAlchemistです。
つまり、この説明を読んでな〜んてことない人になったあなたはAlchemistです。
What's /2
?
/2
というのは引数が2つという意味です。
/0
だと引数が0。
/1
だと引数が1。
専門家の間では、arity(アリティ)と呼ばれます。
>=/2
>=/2を深掘りしてみます。
>=/2の内部実装は以下の通りです。
@doc guard: true
@spec term >= term :: boolean
def left >= right do
:erlang.>=(left, right)
end
2つの引数を:erlang.>=/2
に渡して呼び出しています。
こんな書き方(呼び出し方)はしなくてよいのですが、紹介だけしておくとKernel.>=(4, 3)
と書けます。
他も気になる方は、ドキュメントの</>
を迷わず押してみてください。
ソースコードにジャンプできます。
&>=/2
, &<=/2
, &</2
などは、Function capturing
&>=/2
, &<=/2
, &</2
などは、Function capturingです。
&>=/2
を実行した結果と、fn a, b -> a >= b end
を実行した結果は同じです。
iex> fc = (&>=/2)
&:erlang.>=/2
iex> f = fn a, b -> a >= b end
#Function<43.65746770/2 in :erl_eval.expr/5>
iex> fc.(3, 1)
true
iex> f.(3, 1)
true
iex> fc.(3, 4)
false
iex> f.(3, 4)
false
fn a, b -> a >= b end
を&記法で書くと、& &1 >= &2
となります。
もうここまで来ちゃうと
iex> (&>=/2) == (& &1 >= &2)
true
と、(&>=/2) == (& &1 >= &2)
がtrue
として成立します。
公式ドキュメントは、以下をご参照ください。
その他
何に使うかはこの際、考えません。
以下のようなものを作ることができます。
ソースコード中ではじめてみると、なんだこれ? となること請け合いです。
iex> &+/2
&:erlang.+/2
iex> &-/2
&:erlang.-/2
iex> &++/2
&:erlang.++/2
iex> &<>/2
#Function<43.65746770/2 in :erl_eval.expr/5>
iex> &../2
#Function<43.65746770/2 in :erl_eval.expr/5>
iex> &**/2
&Kernel.**/2
iex> &=/2
#Function<43.65746770/2 in :erl_eval.expr/5>
iex> &==/2
&:erlang.==/2
iex> & &&/2
#Function<43.65746770/2 in :erl_eval.expr/5>
iex> &!/1
#Function<44.65746770/1 in :erl_eval.expr/5>
iex> &in/2
#Function<43.65746770/2 in :erl_eval.expr/5>
iex> &**/2
&Kernel.**/2
Wrapping up
&>=/2
, &<=/2
, &</2
などは、Function capturingです。
Enjoy Elixir
$\huge{Enjoy\ Elixir🚀}$
以上です。
尚々書
先日書いた「Enum.max_by/4 を説明します(Elixir)」の中でもこの記事の内容は一部触れています。
Enum.max_by/4は案外奥が深く、内容が盛り沢山になりました。
&>=/2
, &<=/2
, &</2
は初見殺し感が満載なので、これらに絞って記事を書き起こしました。
I organize autoracex.
And I take part in NervesJP, fukuoka.ex, EDI, tokyo.ex, Pelemay.
I hope someday you'll join us.
We Are The Alchemists, my friends!