LoginSignup
4
1

More than 5 years have passed since last update.

はじめてなElixir(5) / を整数演算にする

Last updated at Posted at 2018-09-17

ちょっぴりマクロで遊んだので備忘録。

はじめてなElixir(4)で div 演算子を Kernel.div じゃなく自分の定義した div 関数を呼ぶようにしたので、いい気になって / 演算子を置き換えます。

どうにも気になる / 演算子

代数としては一つの台集合上に演算が定義されててほしいじゃないですか。なので Elixir で(というか Erlang がそもそもなんでしょうが) / 演算子に整数突っ込んだ結果が浮動小数になるのは残念です。

iex(1)> 1
1
iex(2)> 1 * 1
1
iex(3)> 1 / 1
1.0

ってなんかヘンじゃありませんか? 同じ整数の台の上に居てほしいですよね、

マクロを使ってみる

ということで演算子を自分で定義してみました。
** これは大変危険な匂いがします。未来の自分を混乱させます **

defmodule Overload do
  defmacro m / n do
    quote do
      Kernel.div(unquote(m), unquote(n))
    end
  end
end

これ、そのまま使っても何も起こりません。

iex(2)> 1/2
0.5

もともとの演算子を黙らせてから使います。

iex(3)> import Kernel, except: [/: 2]
Kernel
iex(4)> 1/2
** (CompileError) iex:4: undefined function //2

黙らせてしまったので / の演算自体ができなくなります。

iex(4)> import Overload
Overload
iex(5)> 1/2
0
iex(6)> 1/1
1

さっき定義したマクロを import するとそっちが有効になります。

マクロまで使ってプログラムすることはそんなにないだろうと思います。Scheme/Lisp は、quote を ' unquote を ` を使って積極的に使いたくなる文法にする、ってことをしてますが、Elixir はそうじゃないですし、こういうこともできるんだぐらいで。

参考文献

プログラミングElixir 本の 20.7 節を参照してます。

4
1
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
4
1