コンテンツにスキップ

英文维基 | 中文维基 | 日文维基 | 草榴社区

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

出典: フリー百科事典『ウィキペディア(Wikipedia)』
Elm
Elm
Elmのロゴ
パラダイム 関数型プログラミング、リアクティブプログラミング、純粋関数型言語、関数型リアクティブプログラミング ウィキデータを編集
登場時期 2012年 (12年前) (2012)
設計者 Evan Czaplicki
最新リリース 0.19.1/ 2019年10月21日 (5年前) (2019-10-21)
型付け 静的型付け強い型付け型推論
影響を受けた言語 HaskellStandard MLOCamlF Sharp ウィキデータを編集
ライセンス 修正BSDライセンス[1]
ウェブサイト elm-lang.org ウィキデータを編集
拡張子 .elm
テンプレートを表示

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

歴史

[編集]

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

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

特徴

[編集]

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

不変性

[編集]

Elmのすべての値はイミュータブルであり、一度作られた値に対して後から変更が加えることはできない。

Elmは永続データ構造を用いてArrayDictSetライブラリを実装している[15]

静的型

[編集]

Elmは静的型付けである。すべての定義にはその値を正確に表現する型注釈をつけることができる。型には以下が含まれる。

  • 整数や文字列などのプリミティブ型
  • リストやタプル・拡張レコードなどの基本的なデータ構造
  • タグ付きユニオンと呼ばれるカスタム型[16]

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

モジュールシステム

[編集]

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

HTML、CSS、JavaScriptとの相互運用

[編集]

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

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

制限

[編集]

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

ツール

[編集]

サンプルコード

[編集]
-- 1行コメント

{- 複数行コメント
   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`キーワードを使う
-- 次の型は2分木を表している
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)

脚注

[編集]

外部リンク

[編集]