ElmのインストールとHelloWorldのコンパイル【Elmアドベントカレンダー2014 2日目】
ElmはPlaygroundで簡単にコードを試せますが、最終的にはelm
コマンドでコンパイルする必要があります。
0. バイナリをインストール
MacとWindowは、公式サイトのInstallから、 バイナリをダウンロードできます。
しかし、LinuxではHaskell Platformを使ってソースからインストールしなければなりません。
1. Haskell Platformのインストール
Haskell Platformはapt-get
などでインストールできますが、古い場合があるので新しくインストールした方が良いかもしれません.
cd / curl -L https://www.haskell.org/platform/download/2014.2.0.0/haskell-platform-2014.2.0.0-unknown-linux-x86_64.tar.gz | sudo tar xvzf - sudo /usr/local/haskell/ghc-7.8.3-x86_64/bin/activate-hs
2. cabalのアップデートとElmのインストール
cabal update cabal install cabal-install cabal install -j Elm-0.13 elm-repl-0.3 elm-reactor-0.1 elm-get-0.1.3 echo 'export PATH=$PATH:~/.cabal/bin' >> ~/.bashrc
3. Hello World のコンパイル
cd 【適当なディレクトリ】 echo 'main = plainText "hello"' > hello.elm elm hello.elm firefox build/hello.html
Elmとはどんな言語か?その7つの特徴【Elmアドベントカレンダー2014 1日目】
- これはElm Advent Calendar 2014の1日目です。
Elmはクライアントサイド向けの関数型言語です。一体どんな言語なのでしょうか?
1. HTML/CSS/JSにコンパイルされる
ElmはHTML/CSS/JSにコンパイルして使用します。 この辺はJavaScriptにコンパイルされるAltJSに似ています。 AltJS同様、Elmも特別なランタイムライブラリは不要です。
ただし、Elmは1つのソースでHTML/CSS/JSをすべてまかなえるのが特徴です。
2. 独自の抽象化レイヤーを提供している
代表的なAltJSであるCoffeeScriptは"It's just JavaScript"をモットーにしています。すなわち、文法を改良するのみで、「中身」はJavaScript以上でも以下でもありません。
一方、Elmでは直接JSやCSSを操作することはできません。 基本的にすべてElmの関数・レイアウトライブラリを使わなければなりません。
これはとっつきにくいのですが、逆に見れば「歴史的なしがらみによる汚さ」を扱う必要が無いと言うことです。
ただし、Portsを通じてJavaScriptとやりとりしたり、Canvas風にHTMLに埋め込んで使うこともできます。
3. Haskellベースである
ElmはHaskellを元に若干の修正を加えた独自言語です。
当然Elmは強力な静的型を備えています。 「0に.nameというプロパティはありません」的なエラーとは無縁です。
またあらゆるものは関数です。Array.some
Array.every
どころか、foldl
, map
, etc.. 使い放題です。
4. FRP(Functional Reactive Programing)に対応している
ElmはHaskellベースなので状態や変数はありません。
もちろん、クライアントには状態変化がありまくりです。 マウスの動き、ウィンドウサイズの変更、APIからのレスポンス etc...
JavaScriptの場合は状態変化はonmousemove
などのcallbackを使って関数で明示的に扱うことになります。しかし、callbackが増えてきて、しかもネストしだすと何がなんだかわからなくなります。callback地獄です。
一方Elmでは組み込みの<~
と~
を使います。
main = renderScene <~imageAPIResp ~ Mouse.position ~ Window.width ~ pagingAPIResp ~ (fps 30)
更新の処理はElmが勝手に行ってくれます。
FRPについてはこちらのスライドが大変優れているので、こちらをご覧ください。
http://www.slideshare.net/maedaunderscore/elmfunctional-reactive-programming
5. Playgroundが充実している
ElmはPlaygroundに力を入れています。
GoなどにもPlaygroundはありますが、Elmのは、
と、かなり機能が充実しています。
また、Exampleも基本文法から、応用までそろっています。
ElmのPlaygroundのゆるかわほっこり感は、Haskellの取っ付きにくさを打ち消してあまりあるものがありますね。
6. Haskellだけど怖くない
私はHaskellはこんなイメージです。
確かに、JavaScriptとはシンタックスが全然違うのでとっつきにくくはあります。 最初はコンパイルが通らなくて苦労します。
しかし、ElmはPlaygroundで簡単にトライ&エラーを繰り返す事ができます。 また、「最初の100個の素数を求める」のような人工的な例ではなく、目に見えて実際に動くアプリを作る事ができるので、Haskellよりモチベーションを保ちやすいでしょう。
また、ElmにはFRPがある代わりにElmにモナドはありません。
7. ElmはAnglarJSを置き換える言語である?
既にクライアントサイドには様々なAltJSやライブラリがあるのに、なぜ新しくElmを学ぶのか?
私の場合はAngularJSへの疑問でした。
AngularJSは優れたライブラリで、実際に仕事で使ってもいるんですが、 難しすぎる!
- 3つの異なる言語(HTML/CSS/JavaScript)を同時に扱わなくてはならない。*1→難しい!
- 特定の使われ方(CRUD)に特化していて、汎用性が欠けているように見える→難しい!
- ngBind, ngResource, ngDirective etc… 多い!→難しい!
WEBは10年20年先も存在し続けると思いますが、AngularJSが10年使われるか疑問です。
一方、Elmはシンプルです。
ひょっとしたら、Elmにはクライアントサイドの未来の主流になるかもしれません。 少なくともElmにヒントがあるのは確かです。
関連リンク
まず、これらをよんでモチベーションを高めてから始めるといいと思います。
- 【翻訳】フロントエンドのプログラミング言語をゼロから設計した理由 | POSTD
- 【翻訳】抽象化と組み合わせができるレイアウト言語があれば、CSSは必要ない | POSTD
- 【翻訳】爆速HTML – Elmでの仮想DOM | POSTD
あとがき
明日2日目は「Elmをインストールする」です。
Elm Advent Calendar 2014にはまだ空きがあります。ふるってご参加ください。
*1:場合によってはCoffeeScript、Less、Slimなども学ばなければなりません。
*2:基本的には。HTMLやJavaScriptと連携すれば別です。
~/.bashrcは何も出力してはいけない(するならエラー出力に)
知ってて当たり前の超凡ミス。
起こったこと:rsyncが失敗する
rsyncが何故か失敗してしまう。"protocol incompatibility"と出ていますが、--protocol
オプションを指定しても、最新版のrsyncをインストールしても、同じエラーが出ます。なぜでしょう?
Tue Nov 4 12:15:46 2014 Normal: recursive startup rsync: /home/xxxxxxx/Documents/src/xxxxxxx/ -> vagrant@deva:xxxxxxx/ excluding /cucumber/vendor /cucumber/.bundle ~/.bashrc loaded protocol version mismatch -- is your shell clean? (see the rsync man page for an explanation) rsync error: protocol incompatibility (code 2) at compat.c(174) [sender=3.1.0] Tue Nov 4 12:15:47 2014 Error: Failure on startup of "/xxxxxxxxx".
原因:~/.bashrcでechoしている
上のログに "~/.bashrc loaded" という行があります。これが原因です。.bashrc*1の最後の行で"echo"していました。もちろん、echo以外でも、何かしらの出力をしてしまうとscpやrsyncはコケます。
# ~/.bashrcの最後の行 echo "~/.bashrc loaded"
これと同じ問題です。
bash - SCP doesn't work when echo in .bashrc? - Stack Overflow
How the SCP protocol works (Jan Pechanec's weblog)によると、 scpは初めにリモート側にプロトコルを問い合わせるのですが、~/.bashrcが何かを出力するとそれが混乱してしまうようです。多分rsyncも同様なのでしょう。
回避策:Greetingは標準エラー出力に出す
echo "~/.bashrc loaded" >&2
Goplay: Goで手軽に書捨て環境を作るツール
goreの説明を追記。
LLから、Goに移るときの不満の一つに「標準のREPL(インタラクティブシェル)が無い」があります。
「ポインタはmapのキーになるんだっけ?」のような、つまらない(けど、ありがちな)疑問を解消するには、ドキュメントを漁るより、コードを書いてしまう方が、手っ取り早いですよね?
goplayを作った!
goplayは、書捨てGoコードを書くためのシンプルなツールです。
やっているのは、
1. 一時ディレクトリを/tmp/goplay/
以下に作る
2. main.go
を一時ディレクトリに作る
3. 一時ディレクトリで新しいシェルを起動
4. 環境変数GOPATH
に一時ディレクトリを追加。
これだけです。
インストールはgo get
するだけです。
go get github.com/doloopwhile/goplay
他の方法との比較
ちゃんとしたREPL(gore)を使う
いや、正直、普通はgoreのほうがいいと思います。良い子はgoreを使いましょう。
エディタで書捨てコードを書きたい子はgoplayを使いましょう。
Go Playground
Go Playgroundはブラウザ上でGoを書いて実行できます。 しかし、
- 外部ライブラリをimportできない
- 好きなエディタが使えない という欠点があります。
goplayは、ローカルで実行するので、外部ライブラリもエディタも自由に使えます。
その場でvi a.go
する
まぁ、それでも動くは動くんですが、
package main
の*.go
ファイルが同一ディレクトリに複数あると、
エディタのシンタックスチェッカーが、
「main redeclared in this block」
を出してくるのが五月蝿い。
そして、作ったスクリプトを削除するのも面倒くさい。
Let's go!
Go-GTKでCUIとGUIをつなぐ的なアプリを書いてみた
ごくたまに、ファイルをドラッグ&ドロップで指定できると便利、ということがあります。
スクリーンショット
インストール
go get github.com/doloopwhile/dap
使い方
ドラッグアンドドロップでファイルをバックアップ・ディレクトリにコピーする
mkdir -p $HOME/backup dap | xargs cp {} $HOME/backup
なぜ作ったか
Debian系OSには(dragbox)https://packages.debian.org/ja/sid/dragboxというツールがあるようです。しかし、どういうわけか私のXubuntuでは動きませんでした。
そこで、(Go-GTKのD&Dの例)https://github.com/mattn/go-gtk/blob/master/example/dnd/dnd.goを元に作ってみました。Go-GTKは、デモが充実しており、実用的に使えそうな段階に入っているようです。
Goライブラリを作ったら、とりあえずgodocdown
小さなGoライブラリをつくった時、ほとんど自分しか使わないような規模なら、わざわざREADMEに「Usage」「Example」「Functions」なんて書くのは面倒ですよね。
そんな時は、godocdownで自動生成してしまうのがオススメです。 godocと同等の内容をGitHub用Markdownで生成してくれます。
例:doloopwhile/go-merror · GitHub
go get github.com/robertkrimen/godocdown/godocdown godocdown > README.md
まぁ、わざわざgodocdownでREADMEを作らなくても、 ほっておいてもgodocは、自動で生成されるのですが、READMEを空っぽにしておくのも寂しいので。
地味に待ち遠しいDockerの新機能
DockerfileのENV
コマンドで、複数の環境変数を一度に指定できるようになるらしい。
Allow ENV to set multiple variables in one layer · Issue #2333 · docker/docker · GitHub
従来は複数の環境変数を設定するには、ENVを繰り返さなければなりませんでした。
ENV GOPATH /root/go ENV CGO_CFLAGS-I/opt/fzero/include ENV CGO_LDFLAGS -L/opt/fzero/lib64 -Wl,-rpath=/opt/fzero/lib64
この場合、各ENV
ごとにレイヤーが生成されてしまい、docker push
の際に通信回数が増えるなど無駄でした。
それが1行で書ける=1レイヤーで済むようになるらしいです。 イメージ:
ENV GOPATH=/root/go CGO_CFLAGS=-I/opt/fzero/include CGO_LDFLAGS="-L/opt/fzero/lib64 -Wl,-rpath=/opt/fzero/lib64"