erlang モジュール

見事な3日坊主。
予想通り。
前回書いた話ですが、数字は自動で入るから以下で良いんですね。

 *[タグ1][タグ2]タイトル

そもそも、「保存する」ボタンの横の空白フォームはシカトで良かったっぽい。

モジュール

前置き
  • 全ての関数が属する
  • erlという拡張子のファイルに入れておく
  • コンパイル後のファイルの拡張子はbeam
やってみた
  • calculation.erl
-module(calculation).
-export([calc/1]).
calc({add, ARG1, ARG2}) -> ARG1 + ARG2;
calc({sub, ARG1, ARG2}) -> ARG1 - ARG2.
  • calc関数は2節
    • つなぎ目はセミコロン
  • 各節には、ヘッドとボディがある
  • パターンは関数定義の順に照合される
    • ヘッドそれぞれと照合し、マッチすればボディが実行される

上記コードをコンパイルして使う

1> c(calculation).
{ok,calculation}
2> calculation:calc({add, 5, 9}).
14
3> calculation:calc({sub, 10, 200}).
 -190
  • c(calculation)でcalculation.erlファイルをコンパイルしている
    • 一個上のフォルダに置いている場合等は適宜変更
      • 例:c("../calculation")
気持ち複雑なコードにしてみた
-module(calculation).
-export([calc/1]).
calc({sum, ARG1}) ->
  if
    (ARG1 == 0) ->
      0;
    true ->
      ARG1 + calc({sum, ARG1 - 1})
  end.
  • if文は、ガードがtrueになるまでガードの評価を繰り返す
    • 上記例では、「ARG1 == 0」「true」がガード
  • if文のガードは、少なくとも1つはtrueに評価されなければ、例外が起きる
    • 最後のガードをtrueにしている事が多い
  • "="ではなくて、ガードの場合は"=="
    • "="は照合。"=="は比較
      • erlangにおける"=="は整数or浮動少数の比較の場合のみにしか使う事がなく、コードで出てきたら疑う場所
        • "=:="を使う事が多い。というかそれさえ使っていればイイ
  • ガードはtrueかfalseを返さなければならないので、照合はダメだと思われる
    • この辺りは、そのうち詳しく見る

正直、めっさハマった。(笑

moduleアノテーション

-module(calculation)
  • モジュール宣言
  • calculationのようにアトムの必要がある
  • ファイル最初に記述する必要がある

exportアノテーション

-export([calc/1])
  • モジュール外から呼ぶために必要
  • [calc/1]の1をアリティと言う
    • 要するに引数の数
    • erlangでは慣例的に補助関数に用いるものを同名、異なるアリティにする
    • 補助関数の例は、その内出ると思うので、今回は気にしない
  • 複数書く場合は以下
-export([calc/1, hoge/2])
    • この時、hoge/1は外部から呼べない

今後も、ゆるゆると書いていきます。
というわけで、皆様も色々( `д´)†~~~beamしてみてください。

おまけ

今日のコンパイルエラー

  • 2行目のピリオドを忘れた
1> c(calc).
./calc.erl:3: syntax error before: calc
error

セミコロンすら要らない言語に慣れていると。。。

  • ファイル名とmodule名が違った
    • ファイル名:calc.erl
    • module名:calculation
2> c(calc).
calc.beam: Module name 'calculation' does not match file name 'calc'
error

module名とファイル名は同じにしましょう。

以下は少し複雑なコードを作成中に出たものです。基本的には抜粋

  • if文のセミコロン
    • endの前の式にはセミコロン要らんです
    • endの終わりだからピリオドが付いているわけではないので、お間違えなく
      • 関数の終わりのピリオド
  if
    (ARG1 == 0) ->
      0;
    true ->
      ARG1 + calc({sum, ARG1 - 1});
  end.
  • 存在していない関数
    • 引数がマッチしませんね
    • calc({sum, ARG1})が定義している関数です
  if
    (ARG1 == 0) ->
      0;
    true ->
      ARG1 + calc(ARG1 - 1)
  end.
  • ガードが違反
    • "="は照合なので、ガードでは使えません
  if
    (ARG1 = 0) ->
      0;
    true ->
      ARG1 + calc({sum, ARG1 - 1})
  end.

初心者にありがちな感じですね。
気づいてみれば、「そらそやろ!」って言いたくなります。。。orz