LoginSignup
25
9

More than 5 years have passed since last update.

Swift で Elixir のパイプ演算子を実装してみる

Last updated at Posted at 2017-01-19

最近『プログラミングElixir』を読んでいるのですが、パイプ演算子がすごくいい感じだったので Swift でも同じようなことができないかと思って実装してみました。

先に結果を書くと、こういう感じでそれっぽいことができました。

precedencegroup PipePrecedence {
    associativity: left
    higherThan: AssignmentPrecedence
    lowerThan: TernaryPrecedence
}

infix operator |>: PipePrecedence

func |> <Input, Output> (lhs: Input, rhs: (Input) -> Output) -> Output {
    return rhs(lhs)
}

// 普通ver
let storyboardName = storyboardName()
let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: identifier) as? HogeViewController

// パイプ使うver
let viewController = storyboardName()
    |> { UIStoryboard(name: $0, bundle: nil) }
    |> { $0.instantiateViewController(withIdentifier: identifier) as? HogeViewController }

パイプ演算子って?

『プログラミングElixir』の54ページにあるサンプルコードがすごくわかりやすかったので、コードの部分はそのまま抜粋させていただきます。

普通に書くとこうなるコードがあったとします。

people = DB.find_customers
orders = Orders.for_customers(people)
tax    = sales_tax(orders, 2016)
filing = prepare_filing(tax)

iOS アプリを開発する中でも、メソッドの引数として必要な値を事前に一時変数に入れておく、というのはよく見る光景ではないでしょうか。
これを一時変数使わないで書くとこうなります。

filing = prepare_filing(sales_tax(Orders.for_customers(DB.find_customers), 2016))

読みづらいですね。処理順通りに読むためには後ろから読まないといけないし、2016がどの関数の引数なのかわかりづらいです。
パイプ演算子を使うとこう書けます。

filing = DB.find_customers
           |> Orders.for_customers
           |> sales_tax(2016)
           |> prepare_filing

これすごく読みやすいなと思いました。左から処理順に読めるし、最終的に欲しい結果だけが手に入ります。要するにパイプ演算子は「左の式の結果を右の関数に渡す」演算子なのです。そう聞くと演算子と高階関数を自分で作れる Swift なら実装できそうな気がしますね!
Elixir の場合は右の関数の第一引数に左の結果が自動で入るようになっているのですが、この仕様は Swift では実現が難しそうでした。

思ったこと

Swift は演算子を自分で作れますが、やりすぎると自分しか読めないコードになってしまうだろうなと思ってあまり積極的に使おうとは思っていませんでした。でも、他の言語で採用されている演算子なら採用してみるのもおもしろいかもしれません。

『プログラミングElixir』は読んでいる途中ですが、Elixir は Swift を使っていて Ruby もある程度読める、みたいな人にとってはすごく理解しやすいし、いろんな発見があって楽しめる言語だと思いました!

25
9
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
25
9