Elm (プログラミング言語)

Elmは、ウェブブラウザベースのグラフィカルユーザインタフェースを宣言的に作成するためのドメイン固有プログラミング言語である。Elmは純粋関数型言語であり、ユーザビリティ・パフォーマンス・堅牢性を重視して開発されている。静的かつ強力な型検査によって「事実上一切の実行時例外が起こらない」ことを売りにしている。

歴史 
Elmは2012年にEvan Czaplickiの修士論文として最初に設計された。最初のElmは多くのサンプルコードとそれらをブラウザで簡単に試すことの出来るオンラインエディタとともにリリースされた。Evan CzaplickiはElm開発のため2013年にPreziに入社、2016年からはオープンソースエンジニアとしてNoRedInkに所属し、同時にElmソフトウェア財団を立ち上げた。

最初の実装ではElmコンパイラはHTML・CSS・JavaScriptをターゲットとしていた。一連のツールはその後も拡張を続けており、現在はREPL、パッケージマネージャー、タイムトラベルデバッガー、MacとWindows向けのインストーラーを備えている。Elmはまたコミュニティ製ライブラリを提供するエコシステムを持っている。

特徴 
Elmは小さいながらも表現力豊かな言語の構成要素（if式、let式、case式、匿名関数）を持っている。さらに、不変性、静的型付け、HTML・CSS・JavaScriptとの相互運用性を主要な機能として持っている。

不変性 
Elmのすべての値はイミュータブルであり、一度作られた値に対して後から変更が加えることはできない。
Elmは永続データ構造を用いてArray・Dict・Setライブラリを実装している。

静的型 
Elmは静的型付けである。すべての定義にはその値を正確に表現する型注釈をつけることができる。型には以下が含まれる。
 整数や文字列などのプリミティブ型
 リストやタプル・拡張レコードなどの基本的なデータ構造
 タグ付きユニオンと呼ばれるカスタム型

Elm は完全な型推論をもサポートしており、コンパイラは型注釈なしに型安全かどうかを判定できる。

モジュールシステム 
Elmはモジュールシステムを持っており、ユーザーはコードをモジュールと呼ばれる小さな単位に分割することができる。ユーザーは値をインポート・エクスポートすることができ、実装の詳細を他のプログラマが意識する必要のないように隠蔽することができる。モジュールはElmコミュニティライブラリの基礎になっている。

HTML、CSS、JavaScriptとの相互運用 
Elmはポートと呼ばれる抽象を用いてJavaScriptと協調することができる。これによってElmとJavaScriptの間でデータのやりとりが可能になる。

Elmはelm/htmlというライブラリによってElmの内部でHTMLやCSSを扱うことができる。これはVirtual DOMを使って効率的に更新を行う。

制限 
HaskellやPureScriptと違い、Elmは型クラスをサポートしていないため、多くの共通的な処理を抽象化することはできない。たとえば、map、apply、fold、あるいはfilterといった汎用的な関数はない。代わりに、List.map Dict.map のように、それぞれのモジュール名でプレフィックスをつけて使う。

ツール 
 オンラインエディタ（簡単な確認用） elm-lang.org/try
 ローカルへのインストール Install Elm
 学習用リソースとサンプル集
 コアライブラリとコミュニティライブラリ

サンプルコード 
-- １行コメント

{- 複数行コメント
   It can span multiple lines.
-}

{- 複数行コメントは {- ネスト -} することができる -}

-- ''greeting'' という値を定義している。型は String と推論される。
greeting =
    "Hello World!"

-- トップレベルの宣言には型注釈をつけた方が良い
hello : String
hello =
    "Hi there."

-- 関数も同じように宣言される。引数は関数名の後ろに書く。
add x y =
    x + y

-- やはり型注釈をつけたほうが良い
hypotenuse : Float -> Float -> Float
hypotenuse a b =
    sqrt (a^2 + b^2)

-- 関数はカリー化されている。ここでは掛け算の中置演算子を 2 で部分適用している。
multiplyBy2 : number -> number
multiplyBy2 =
    (*) 2

-- 条件分岐には if 式を使う
absoluteValue : number -> number
absoluteValue number =
    if number < 0 then negate number else number

-- 名前つきのフィールドを保持するにはレコードを使う
book : { title : String, author : String, pages : Int }
book =
    { title = "Steppenwolf"
    , author = "Hesse"
    , pages = 237 
    }

-- `.`でレコードの値にアクセスする
title : String
title =
    book.title

-- `.`でのレコードのアクセスは関数として使うことも出来る
author : String
author =
    .author book

-- 新しい型を定義するには`type`キーワードを使う
-- 次の型は２分木を表している
type Tree a
    = Empty
    | Node a (Tree a) (Tree a)

-- これらの型はcase式によって分岐することができる
depth : Tree a -> Int
depth tree =
    case tree of
        Empty ->
            0

        Node value left right ->
            1 + max (depth left) (depth right)

脚注

外部リンク 
 

ドメイン固有言語
関数型プログラミング言語