requirettyを全力で回避した話
会社で作業をするために使うスクリプトをOCamlで書いてやりました。
で、この過程でrequrettyに苦しめられたのでその辺のメモ。
requiretty外せないサーバ上でsudoしてからコマンド実行しないといけない、呪われた運命を背負った ”>魔法少女 開発者の助けになればな、と。
会社で作業をするために使うスクリプトをOCamlで書いてやりました。
で、この過程でrequrettyに苦しめられたのでその辺のメモ。
requiretty外せないサーバ上でsudoしてからコマンド実行しないといけない、呪われた運命を背負った ”>魔法少女 開発者の助けになればな、と。
うちの会社は割といろんな言語を使っているエンジニアがいるのですが、OCamlerは少なそうだったのでOCamlを布教するべく、OCamlでWebサービスが作れるOcsigenの紹介LTをしてきました。
簡単にOcsigenを題材に選んだ流れをまとめると、
先週月曜(2014/07/07)に全社ハッカソンがあった
→せっかくなのでOcsigenでなんか作りたかった
→チュートリアルの途中で力尽きた
→社内LTの発表順が翌週だったので、土日使ってチュートリアルを最後まで終わらせてネタにすることにした
というような感じでした。
本当はチュートリアルで終わらずにアプリを作りたかったのですが、思いのほか環境構築のほうに手間取ったためにたどり着けませんでした…
まぁ思いのほかOcsigenのモジュール構成が複雑だったので、ある程度習熟しないと一朝一夕でなんか作るのはしんどそうでしたが。
なぜかふと思い立って、BefungeのインタプリタをOCamlで実装してしまいました。
Befungeってどんな言語? というと、↓がHello,worldのソースファイルになるような言語です。
ちなみにこのソースはWikipediaのものをそのままお借りしています。
v @_ v >0"!dlroW"v v :# < >" ,olleH" v ^ < |
WP-Codeboxでハイライトされない……
まぁ、さすがにこんなところまでサポートしてないですよね。
Brainfu*kはあるみたいですが。
副作用はなるべくないほうがよい。
それはそうなんですが、副作用を使ったほうが効率がよかったり、コードの見通しが良くなったりすることもよくある話です。
例えば、以下のような単純な表示関数printを考えます。
let print s = Format.printf "%s@." s |
当然ながら、呼び出すと以下のように引数の文字列をそのまま表示します。
# print "a";; a - : unit = () # print "b";; b - : unit = () # print "c";; c |
OCamlで使える標準ライブラリは、最初に触れた時こそ「すげー、集合とか標準で使えるの!?」とか思ってたものの、実際触っていると「あれ? Setってof_listないの?」とか「え? リストのconsって関数として用意されてないの?」とか「うわっ……私の年収、低すぎ……?」など、いろいろな不満が出てきます。最後のは関係ありませんが。
調べてみたところ、あれは標準ライブラリではなくすとっどりぶなのですね……
それならしょうがない。
普通ならCoreとかBatteriesとか入れるんでしょうが、変な依存性入れたくないですし、これまで組んだプログラムを修正するのも面倒なので、勉強も兼ねて自分で互換性持たせたまま拡張してみることにしました。
先日、OCamlでモナドっぽいものを作ったという記事を書きましたが、それも拡張の一貫ですね。
というわけで、覚え書きも兼ねて、詰まった部分などをまとめておきます。
ライブラリの拡充と関数型言語のお勉強を兼ねて、モナドっぽいものを実装して見ました。
単純にモナドをOCamlで使いたいだけならMonad拡張を入れる方が手っ取り早いですが、あまり外部ライブラリへの依存性を入れたくないのと、OCamlの記法の中だけでどこまで出来るか試してみたかったので。
ちなみに誤解を避けるため先に断っておきますが、自分はHaskellerではありません。
以下ではモナドに関してHaskellをかなり参考にしていますが、Haskellのモナドに対する勘違いなどが含まれている可能性があります。
ご了承下さい。
OCamlでは、modは特別扱いで中置記法として定義されています。
# (mod);; - : int -> int -> int = # 5 mod 3;; - : int = 2 |
たとえばこの別名でremという関数を作りたくても、これを中置記法で定義することは出来ません。
# let (rem) x y = x mod y;; Error: Syntax error |
これは、中置演算子として定義できる文字列が、記号の特定の組み合わせ、もしくは予約された文字列、というふうに決められているからですね。
中置演算子として予約された文字列にはor,mod,land,lor,lxor,lsl,lsr,asrがあります。
(参考:公式マニュアルのinfix-opの項)