LoginSignup
31
10

More than 3 years have passed since last update.

この記事は、fukuoka.ex Elixir/Phoenix Advent Calendar 2020 6日目です。
前日は、 hisawayさんの [Elixir]匿名関数をパターンマッチする でした。

最近もくもく会でやっていた事を紹介します。
配列の要素数をカウントする関数です。

def listlen(l):
    if (l == []):
        return 0
    else:
        return 1 + listlen(l[1:])

print(listlen([1,2,3,4]))

やってしまいました。
elixirの割にendが無いと思ったらpythonですね。
書き直します。

def listlen(l)
  if l == [] then
    0
  else
    1 + listlen(l.drop(1))
  end
end

puts(listlen([1,2,3,4]))

endをつけてreturnが不要になりました。
(最後の行の値は暗黙にreturnされる)
でもelixirはdefmoduleの中でしか関数定義できないので
これはrubyのコードです。

(defun listlen (l)
  (if (null l)
    0
    (+ 1 (listlen (cdr l)))))

(listlen (list 1 2 3 4))

今度こそ!・・・括弧が沢山増えてしまいました。
common lispです。

-module(listlen).
-export([listlen/1]).

listlen([]) -> 0;
listlen([_|T]) -> 1 + listlen(T).

うーん、括弧は減りましたがちょっとサッパリしすぎです。
これはerlangです。
erlc listlen.erlでコンパイル後に
erlで対話モードを起動して
listlen([1,2,3,4]).で実行します。
erlangでは;は行の区切りではなく
この行の関数の引数、
listlen([]) -> 0([])
に一致しない場合は次のlistlenを実行すると言う意味です。
最後に実行するlistlenには.を末尾につけて
これが最後のlistlenだよとerlangに教えます。

defmodule ListLen do
  def listlen([]) do
    0
  end

  def listlen([_|tail]) do
    1 + ListLen.listlen(tail)
  end
end

ListLen.listlen([1,2,3,4])

ようやくたどり着きました。
こいつがりんごろう
これがelixirのコードです。
elixir listlen.exsで実行します。

あとがき

そこはかとなくオライリー風に。
最初マクロについて書こうとしたけど
elixirマクロの記事そこそこあったんで
こっちにしました。

31
10
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
31
10