2015年1月11日日曜日

Rustを習得したい

実は去年(2014年)の抱負だったのだけど、実践できなかったし、今年こそRust 1.0が出る予定なので、記事にして晒しておこうと思う。所謂新年の抱負です。


第二プログラミング言語候補

プログラミングが義務教育になるというのなら、プログラマーはプログラミング言語を少なくとも3つ以上は流暢に使えないといけないわけじゃない!!

冗談はさておき、時々、Rubyが苦手とする、もしくは得意としない分野を他の言語で解決したいという場面がある。
どういう時かというと、並列処理をしたい時(Rubyでもできるけど)と、 低レイヤーなこと、もしくは何かの拡張を書きたい時。

並列処理の場合、


DockyardはElixirで行くらしい

低レイヤーや何かの拡張やモジュールを書く場合、

  • C/C++
かな。
ものによるとけど、Apache/Nginx/DB/RubygemsでC拡張あたりが対象。
Luaも候補に入るのが普通なのかもしれないけど、何ができるのかはよくわかってない。結局Cとセットで使うのかな?って印象。mrubyもCを使える方が良い。ので、C/C++一択にしてる。


あと、処理系が入っていない環境向けの場合、

かな。環境によっては、Bash/Perl/Pythonでも良いと思うけど。


すごく漠然としてるけど。個人的にはそんな感じ。ちなみにフロントエンドでのJavaScriptはそれなりに使える。あれはもう共通言語なので除外。


Goも習得せねばとは感じている

Goブームの第2波のようなものが去年か一昨年くらいからあって、Go製のツールがちらほら出てきた。
Python/C++で書かれるものが、Goで書かれるようになったという印象。今話題のDockerやその周辺ツールもGo製。HerokuのCLIGithubのCLIもGoになりつつある(なった? Github CLIをGoに移行するIssue)

Goを読み書きできる方が幅が広がるし、ちょっとしたツールならGoで作ってしまう方が良いのかもしれない。


GoよりもRustが好きかも

Goをディスるつもりもないし、使わないつもりもないし、GoとRustを比較するのがそもそも間違いという点があるかもしれないけど、個人的にはRustの方が好きかもしれない。

Goの文法はシンプルでそれがいいんだ!というのも一理あると思う。
けど、Goを書いていて、引っかかる点がある。
なんとも言葉に言い表し難いんだけど、「ぱっと書いたコードだから綺麗にしたい(インデントとかではなく設計的に)」という時に、その方法がないというか、よく分からない。なるべくGoの文化に合わせておきたいけど、でもジェネリックとか使いたいじゃん、みたいな感じ...。ジェネリックはいずれ実装されるのかな。あと、ものすごくどうでもいいことだけど、「public = 大文字で始まる」というのがいただけない。Printlnとか。


読んでいて共感した記事:

パターンマッチを使いたい場面はある。知ってれば使いたくなるという場合に、Goにはそれがないというのが多いのかも。
個人的に、GoはPHPに似ていて、真剣にお付き合いするのではなく、時々会って良いとことダメなところを感じながら過ごす感じで接してるかもしれない。
別に嫌いでもないし、いいところもあるんだけど、合わない。そんな感じ。


なぜRustなのか

やっと本題

Rustを選ぶにあたって重視しているのは以下の点

  • 安全なプログラミング
  • 高水準言語のようなシステムプログラミング言語
  • パッケージ管理(Cargoとcrates.io)
  • FFI
  • 簡単に始められそう


安全なプログラミング

並列処理を書くときに、競合状態や、意図しないメモリの操作などは避けたい。とくに、Cで書く場合、ポインタという低レイヤな操作をすることがあるけど、これを間違うと非常に危ない。メモリのどの番地をさしているかのようなものなので、並列処理関係なく、間違った時点で他のクリティカルなデータが見えたりしては大変なので、基本的に触りたくない。(けど、Cでやる=ポインタは大概ついてくる)

C++にはスマートポインタというのがあるようで、うまく使えばそういうのは避けられるのかもしれないけど、C++って複雑そうっていう印象だけで避けて生きてきている。(すみません)

IPAのレースコンディションの一般的対策が解りやすいのだけど、ここに書いてある対策法の一つがアクセス権によるもので、RustはそれをOwnershipという仕組みので言語自体に取り入れている。
そしてさらに2つ大事な点があって、これがコンパイル時に厳格にチェックされるのでミスを未然にほとんど防げるということと、他の開発者が書いたコードもそのチェックがされているということ。C/C++で、何が怖いかというと、自分の書くコードもそうだけど、自分がよくわかってない場合に、他人のコードを取り込むこと。コンパイラが優秀なのはありがたい。ちなみにエラー文も解りやすいし親切。

とはいえ、Rustはシステムプログラミング言語なので、リスクのある危険なコードを許容するためにunsafeというのがある。区別されるだけでも個人的にはすごくありがたい。


高水準言語のようなシステムプログラミング言語

Rust by ExamplesHyperPencilを見ると分かるけど、HLLのような簡潔なコードを書ける。Brooksの生産性不変の法則が正しいのなら、記述量は少ない方が良い。


パッケージ管理

Bundlerのようなパッケージ管理がある言語の方がありがたい。RustにはCargoとそのセントラルレポジトリのcrates.ioがある。CargoがBundlerのようなもので、crates.ioはRubyでいうところのRubygems.org。Rustをインストールすると、Cargoも一緒にインストールされる。素晴らしい!

Goには公式のセントラルレポジトリにあたるものがなく、各ライブラリのダウンロード数は見れないし、検索もGo Searchという、公式なのか非公式なのかよく分からないbootstrapそのままのサイトでやるしかない。レートはgithub上のimportで読まれてる件数とリポジトリのstarの件数からなんだろうか。


FFI Rubyの拡張をRustでも書ける

実は、他のプログラミング言語を習得しようとしたきっかけが、「Rubyだと遅い > 高速化したい > 並列化したい > でもRubyも使いたい > C拡張 > C怖い」なので、この点はすごく大事。全て別言語でやるってのもいいんだけど、普段からRubyが良いし、Rubyに必要な分は自分で補えるようになりたいという個人的な強いこだわりがある。

もともと本来の目的だけど、今はそれほど必要に迫られていなくて試していない。
けど、参考になる情報があるのではっておく。

Goでも書けるのか調べた気がするんだけど、GoのFFIが微妙か、両方の言語にGCがあるのが良くないってのを見かけた気がして(情報元を忘れた)、やってないんだけど、今見たら、できなくはなさそう。改善したのかな?偏見だったのかも。(汗


簡単に始められそう

1.0が出て、日本語の情報も増えればの話だけど、インストールは簡単だし、実行も簡単。


Sublime textでRustの自動補完をしたい場合は、RustAutoCompleteを使うと良い。Rustのソースコードracerを入れる必要があるけど、インストール手順はそれぞれ書いてある。


1.0が出るまでは、言語の仕様変更がまだまだあるだろうし、crates.ioにあるライブラリが追いつくのもそれぞれ時差があるだろうから、標準ライブラリを使ってちょっとしたコードを書くところからやっていってる。
毎回rustcを叩くのは面倒なので、今はRubyのGuardでやっているけど、そのうちcargo-watchというのを入れてみようかなぁ。


Rustには、パターンマッチやジェネリックやら、モダンなプログラミング言語が持っている機能が最初から備わっている。
そういう点でも触れていて楽しい。
Borrow Checkerとはまだ仲良くなれていない。
HaskellやC++をやっていれば、すんなりできそうな知らない概念のようなものがあるように思うし、
それを公式のドキュメントで説明しているものはなさげ。なかなか敷居が高いようにも思う。
けど、1.0リリースまでにはなんとかそれなりにRustできるよ!って言えるようになりたい。


追記: 他のサンプルコード

coreutilsのRustの実装が参考になるかも。
前にwcの実装ってどうなってるんだろうと気になってソースを見てみたときに、Cのwcの実装を見て、機能の割にコードがたくさんでびっくりしたことがあったなぁ。Rustのwcは、コメントがほとんどないけど、1/3くらいかな。速度は測ったことがないけど、Cの方が速いんだろう。

0 件のコメント: