この記事は、Elixir Advent Calendar 2024 シリーズ8 の11日目です
昨日は、@RyoWakabayashi さんで 「Advent of code 2024 Day 8 Part 1 & Part 2 を Livebook で楽しむ
」 でした
piacere です、ご覧いただいてありがとございます
19時間前にリリースされたElixir 1.18に搭載の「型推論」を試してみます
なお、このコラムが、面白かったり、役に立ったら、 をお願いします
Elixir 1.18のビルドとインストール
Elixir 1.18は、2024/12/11段階で、asdfやapt、Precompiledがリリースされていないため、自前でビルドが必要です
git clone https://github.com/elixir-lang/elixir.git
cd elixir
make
おや? … 上記GitHub公式の手順だと、Elixir 1.19.0-devがインストールされるようですね … ま、いっか
「型推論」を試してみる
CHANGELOG のトップにある、関数呼出と戻り値、パターンマッチにおける型チェックエラーを試してみます
defmodule User do
defstruct [:age, :car_choice]
def drive(%User{age: age, car_choice: car}, car_choices) when age >= 18 do
if car in car_choices do
{:ok, car}
else
{:error, :no_choice}
end
end
def drive(%User{}, _car_choices) do
{:error, :not_allowed}
end
end
User.drive({:ok, %User{}}, car_choices)
CHANGELOGによると、下記のような型チェックが走るそうです
Elixir 1.18からは、こうした型推論に基づく型チェックが、型定義をコードに一切書いていないのに可能となるってのは、ワクワクしますね
warning: incompatible types given to User.drive/2:
User.drive({:ok, %User{age: nil, car_choice: nil}}, car_choices)
given types:
{:ok, %User{age: nil, car_choice: nil}}, empty_list()
but expected one of:
dynamic(%User{age: term(), car_choice: term()}), dynamic()
where "car_choices" was given the type:
# type: empty_list()
# from: lib/foo.ex:21:17
car_choices = []
typing violation found at:
│
22 │ User.drive({:ok, %User{}}, car_choices)
│ ~
│
└─ lib/foo.ex:22:10: Example.run/0
しかし、サンプル通りだと、iexでは下記エラーが出ます
** (FunctionClauseError) no function clause matching in User.drive/2
The following arguments were given to User.drive/2:
# 1
{:ok, %User{age: nil, car_choice: nil}}
# 2
[]
iex:7: User.drive/2
iex:17: (file)
そもそも、関数定義と異なる呼出サンプルのようなので、下記呼び出しに直してみます
User.drive({:ok, %User{}}, car_choices)
そうすると今度は、やはり異なる下記エラーが出ます
error: undefined variable "car_choices"
│
2 │ set -e
│ ^^^^^^
│
└─ iex:2
** (CompileError) cannot compile code (errors have been logged)
まぁ、そりゃ car_choices
が未定義なので、そうなりますよね
上記型チェックエラー時に given types:
で empty_list()
と出ているのをヒントに、car_choices
を試しに下記のように定義してみます
car_choices = []
この場合は、下記のように普通に通ってしまいました … うーん、どうやって型チェックを起こしたら良いんだろう?
{:error, :no_choice}
また分かったら、続報コラムを書くとします
p.s.このコラムが、面白かったり、役に立ったら…
明日は、 私で 「【再戦】19時間前にリリースされたElixir 1.18に搭載の「型推論」が上手くいった(御大José Valimとのやり取りも)」 です