16
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ElixirAdvent Calendar 2022

Day 12

is_number/1 の実装を追いかけてみることを楽しむ(Elixir)

Last updated at Posted at 2022-04-06

白露に風の吹きしく秋の野はつらぬきとめぬ玉ぞ散りける


Advent Calendar 2022 88日目1の記事です。
I'm looking forward to 12/25,2022 :santa::santa_tone1::santa_tone2::santa_tone3::santa_tone4::santa_tone5:
私のAdvent Calendar 2022 一覧


はじめに

Elixirを楽しんでいますか:bangbang::bangbang::bangbang:

My Advent Calendar 2022 goes behind 8 days.
NP.

is_number/1を読んでみます。

is_xxx Guards

あるtermがあったときにそれが何であるのかを判定するGuardsと呼ばれるものがあります。

is_という接頭辞で始まります。
以下のものがあります。
たとえば、is_atom/1は、termAtomである場合にtrue、それ以外の場合にはfalseが返ります。

is_number/1

上記の中で、is_number/1は、termが整数やFloatである場合にtrue、それ以外の場合にはfalseが返ります。

どういうふうに実装されているのだろうと気になりました。
気になったものは仕方ありません。
人間の好奇心は誰にも止められません。

もう少し言葉にしてみると、ある変数を宣言するときにElixirでは型とともに宣言しないので、型がなにであるかを確かめるのは結構複雑なことをしないとわからないのではないかとおもいました。
複雑なElixirの実装に出会えるのではないかとワクワクドキドキしました。
はたしていかに:interrobang:

調べたことは、Qiitaに書いておきます。

[</>] を押してみます

is_number/1のドキュメントに行きます。

[</>]のリンクを押してみましょう。

迷わず押せよ!
押せばわかるさ!
ありがとう!

lib/elixir/lib/kernel.ex
  def is_number(term) do
    :erlang.is_number(term)
  end

ほうほう、たったのこれだけでした。
Erlangのis_numberを呼び出していました。

Erlangのis_number

Erlangに深入りしてみます。

erts/preloaded/src/erlang.erl#L2262-L2266
%% Shadowed by erl_bif_types: erlang:is_number/1
-spec is_number(Term) -> boolean() when
      Term :: term().
is_number(_Term) ->
    erlang:nif_error(undefined).

最後はCで実装されているようです。
断片だけ示しておきます。
ちゃんと追えているのかあんまり自信はありません。

erts/emulator/beam/erl_term.h
#define is_number(x)		(is_integer(x) || is_float(x))

ここからは、is_integerのほうに進んでみます。

erts/emulator/beam/erl_term.h
#define is_integer(x)		(is_small(x) || is_big(x))

また ||になっています。
ここからは、is_smallのほうに進んでみます。

erts/emulator/beam/erl_term.h#L263
#define is_small(x)	(((x) & _TAG_IMMED1_MASK) == _TAG_IMMED1_SMALL)

erts/emulator/beam/erl_term.h
#define _TAG_IMMED1_MASK	0xF

erts/emulator/beam/erl_term.h
#define _TAG_IMMED1_SMALL	((0x3 << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_IMMED1)

スクリーンショット 2022-04-06 23.10.05.png

調べ方は、Erlangのリポジトリで、左上のSearch or jump to...にキーワードを打ち込んで、でてきた結果を眺めました。
並べました。


Wrapping up :lgtm::lgtm::lgtm::lgtm::lgtm:

Enjoy Elixir:bangbang::bangbang::bangbang:
$\huge{Enjoy\ Elixir🚀}$

is_number/1の実装を追いかけてみました。
Erlangのis_numberを呼び出しているだけでした。

Erlangに入ってからは、ちゃんと追いかけられているかどうかはあんまり自信はありません。

以上です。

  1. @kaizen_nagoya さんの「「@e99h2121 アドベントカレンダーではありますまいか Advent Calendar 2020」の改訂版ではありますまいか Advent Calendar 2022 1日目 Most Breakthrough Generator」から着想を得て、模倣いたしました。

16
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?