このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

Erlang実験室:レコードの必要性はそんなに高くない

「Erlang実験室:例外的値とバリアント型データ」において、Erlangでは例外の使用が少ない気がすると言いました。その理由として、「やたらに自由度が高いバリアント型があるからだろう」と推測しました。同じ理由により、レコード型も意外に使われてない気がします(また「気がします」で統計的裏付けはない)。

例えば、person型レコードは次のように定義できます。(以下の定義はこのままコンパイルできますが、フィールドの型は単なる注釈で実際的意味を持ちません。)


-record(person, {
name::string(),
age::integer(),
mail_address::string()
}).

このレコード定義と同等な定義は、他のプログラミング言語でも書けます。例えばCなら:


struct Person {
wchar_t *name;
short int age;
wchar_t *mail_address;
};

ですが、こんな定義をしないで、単なるタプルをperson型データと思って使うことが多いようです。その理由は:

  • タプルの項目数が2つや3つなら、フィールド名がなくても順番や意味をおぼえられる。
  • しちめんどくさいレコードの構文を使うより、直接に、リテラルやパターンマッチングを使うほうが楽。

それとですね、レコードは定型のタプルなので、Erlangの“やたらに自由度が高いバリアント型”のメリットが失われるんですよね。具体的に言うと、Erlangでは、person型を次のように定義することができます。(言語仕様で定義できるわけではなくて、習慣的な型記述構文。)


Person = ( atom() | string() |
{(atom() | string())} |
{(atom() | string()), integer()} |
{(atom() | string()), integer(), string()} )

これだと、{"tonkichi", 27, "tonkichi@tozai-travel.example.jp"} に対して次のような省略ができます。

  1. メールアドレスが不要なら、{"tonkichi", 27}
  2. 年齢も不要なら、{"tonkichi"}
  3. タプルにしなくてもいい "tonkichi"
  4. アトムだっていい tonkichi
  5. タプルの項目もアトムでよかった {tonkichi, 27}

実に自由気ままです。そんなデータ使ったら処理が鬱陶しいだろうって? そうでもないんですよ。次のようなパターンマッチングで場合分けできます。


case Person of
Name when is_atom(Name) ->
% アトムのとき
Name when is_list(Name) ->
% 文字列(リスト)のとき
{Name} ->
% 1項目のタプルのとき
{Name, Age} ->
% 2項目のタプルのとき
{Name, Age, MailAddr} ->
% 3項目のタプルのとき
end

でもね、可読性やドキュメンテーションの観点からは、使えるならできるだけレコードを使ったほうが望ましいと思いますよ。