バージョン1.0が見えてきたElmが良さげなのでお試し。
バージョン0.19がリリースされ、その先にバージョン1.0が見えてきたというElm。
『今勢いのある言語 Elm』という勢いあるエントリーに乗っかって、入門してみた次第。インストールやコマンド体系などが今までのバージョンと違うようだったので、備忘録をここに記す。
##入門者のスペック
Haskellは以前に2冊くらい本を読んだ程度。Scalaはベターjavaとして実案件で活用。普段はPythonを使う。趣味は、同じくバージョン1.0出るか出たよが話題となる、NimとJulia。以前、フロントエンドも自前で書いた時に辛かったので、Immutableな言語で仮想DOMを操作してフロントエンドを完結できるならいいねと、Elmに期待(加えて、Mutableな処理をガリガリ書く必要があるならば、Nimでwebassemblyといきたいところ)。
##時短に役立つ『Elm入門ハンズオン』
https://gitpitch.com/ababup1192/elm-handson1/master?grs=github&t=sky
カーソルキーを上下左右に動かしながらElm入門ができる素晴らしい資料。
本ハンズオンは、Elm0.18対応と思われるが、Elm0.19でもほぼほぼ動いた。
ブラウザ上の動作に特化したElmは、HaskellやScalaやNimに比べるとシンプルな言語仕様と思われ、言語仕様を軽く眺めDOMをいじってみるまでは、1時間ほどで行えた。
#Elm 0.19に速攻入門記
(当座の)インストール方法
リリースされたばかりのElm0.19は、npm経由のインストールが推奨されていない(できない場合がある)模様。そのため、以下の指示に従う。
いずれのプラットホームも簡単に入りそう。
Linux(debian等)の場合:
Elm 0.19 just came out, so the npm
installer is not ready yet. In the meantime, you can download it manually like this:
wget "https://github.com/elm/compiler/releases/download/0.19.0/binaries-for-linux.tar.gz"
tar xzf binaries-for-linux.tar.gz
sudo mv elm /usr/local/bin/
ということで、elmのお試しだけならnode.js./npmは必要ない(mvにsudoが必要なのは、Windows 10上のWSL debianなどの場合)。
まずは、elm init
elm0.19では、作業ディレクトリにて、
elm init
とするのがお作法な模様。Scalaでいうsbtのようなものか。
kmry:/mnt/c/dev/elm1$ elm init
Hello! Elm projects always start with an elm.json file. I can create them!
Now you may be wondering, what will be in this file? How do I add Elm files to
my project? How do I see it in the browser? How will my code grow? Do I need
more directories? What about tests? Etc.
Check out <https://elm-lang.org/0.19.0/init> for all the answers!
Knowing all that, would you like me to create an elm.json file now? [Y/n]: Y
Okay, I created it. Now read that link!
kmry:/mnt/c/dev/elm1$ tree .
.
├── elm.json
├── elm-stuff
│ └── 0.19.0
│ ├── Elm_Repl.elmi
│ ├── Elm_Repl.elmo
│ └── summary.dat
└── src
kmry:/mnt/c/dev/elm1$ cat elm.json
{
"type": "application",
"source-directories": [
"src"
],
"elm-version": "0.19.0",
"dependencies": {
"direct": {
"elm/browser": "1.0.0",
"elm/core": "1.0.0",
"elm/html": "1.0.0"
},
"indirect": {
"elm/json": "1.0.0",
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.0"
}
},
"test-dependencies": {
"direct": {},
"indirect": {}
}
}
...だいたい雰囲気はわかるだろう。elm.jsonに必要なパッケージを記していくものらしい。
##次いで、elm reactor
開発用のwebサーバー(reactor)を立ち上げながら、エディタでelmコードを書いていくというのが流儀らしい。エラーが出た場合もブラウザ上で確認する。
kmry:/mnt/c/dev/elm1$ elm reactor
Go to <http://localhost:8000> to see your project dashboard.
http://localhost:8000にアクセスしてみる:
ということで、src配下にコードを書いていくらしい(自分の場合、VS-codeにelm拡張を入れた。)。
hello worldも、仮想DOM経由で行うのが流儀だろう。
helloとworldを宣言し、mainでつなげる:
import Html exposing (..) --(h1, div, p, text)
hello = h1 [] [text "hello"]
world = p [] [text "world."]
main =
div [] [ hello , world]
import Html exposing (..)することで、h1, div, pなどの仮想DOM要素一式と、何もタグで囲まれていない文字列Html a を作るtextとが使用可能となる。
次いで、関数型言語らしく(?)、関数を使ってみよう。
import Html exposing (..)
-- 識別名称をエイリアス宣言
type alias Name = String
type alias Age = Int
type alias Person = { name : Name, age : Age }
-- 代入用変数(≒オブジェクトの生成)
takeshi = { name = "剛田武", age = "10" }
nobi = { name = "野比のび太", age = "9" }
--表示用DOMの生成
get_text x s = text (x ++ s)
name_age x =
div [] [
h1 [] [get_text x.name ":"] ,
h2 [] [get_text x.age "歳"] ,
hr [] []
]
--mainを介し、仮想DOMを描画
main =
div [] [
name_age(takeshi) ,
name_age(nobi)
]
実行結果:
『hr [] []』ってなんのことだろうとか若干気になるが、ともあれ,変数・関数を駆使し、ブラウザのDOMに反映できていることはわかるだろう。
ここから先は、ラジオボタンやプルダウンなどで、スネ夫やしずかちゃんを登場させるところは略する。ていうか、ボタンを用意するからには、サーバ側とデータをやり取りしたいよねと思ったあたりで、1時間経過したので、そのあたりの入門は今後の課題とする。
#おまけ(Haskellになじみがない方向け):elm repl
node.jsが入っている環境では、elm replとタイプすることで、nodejsを活用したREPL環境でHaskell風なElmの関数型言語テイストな記述をお試しできる。
Haskell風な体系では、f(x)はf x とも記せる:
> f x = x^2
<function> : number -> number
> f 5
25 : number
> f (3)
9 : number
> g (x) = x*2
<function> : number -> number
> g 4
8 : number
> g (2)
4 : number
このかっこが省略できる記法に慣れておくと、関数渡しの場合などに可読性が向上すると思っている。
例えば、
> f (g 2)
16 : number
の場合、カッコ内のg 2を先に評価し、f(結果)を得ると読める。
ElmをHakellライクな言語として入門する場合には、REPLを使うのが良さそう。
> h x = if x > 4 then True else False
<function> : number -> Bool
> h (5)
True : Bool
> h (f 5)
True : Bool
> h (f 1)
False : Bool
#0.19で、ちょっと困ったこと。
整数型を文字列型に変換する、toStringが使えなかった。モジュール体系が変わったからなのかな???
まぁ、Elmで仮想DOMな雰囲気は体験できたから良しとする。