ろじかるんるんものがたり

病人が特に何も書かない。無駄だからだ。

Rust は何が新しくないのか

disclaimer

追記で注意書き足すのはどうなんでしょうね。ということで追記です。

  • 別にギョムでガンガン書いてるとかではないです。
  • ノミコンの方も含めてドキュメント全部読んだ、API 一通り眺めた、型推論というかリージョン推論部分の概要眺めた、関連する論文読んだ、言語触った、程度の人間が書いてます。
  • 正しくない、不正確な部分もあると思います。
  • 雑です、すいません。

TL;DR 的には、C++ 置き換えるための言語として作られたので当然 C++ にあった概念引き継いでますよみたいな話です。

以下追記前の元の全文。

以下の記事が結構人気と聞きました。

Rustは何が新しいのか(基本的な言語機能の紹介) - いもす研 (imos laboratory)

ここでは、記事中の「新しくない」部分を historical な話を交えて説明する形で何か書きたいと思います。

記事を否定するようなものではないです。寧ろよくまとまっていると思うのですが、綺麗にまとまりすぎていて「分かっている人にしか分からない」部分があるかな、と思い、筆を(キーボードーですけど)取った次第です。対象読者は GC のある言語でしかコードを書いたことが無い人、なのかな。

「Rust のプログラミング言語としての立ち位置」補足

元記事では、言語の今と未来について書かれていますが、ここでは昔話をしましょう。

Mozilla は様々なプロダクトを過去 C++ で実装してきました。巨大なプロダクトが多く、開発には自作の静的解析ツールが利用されていました。

しかし、問題が起きます。静的解析ツールが利用していた C++ をパースするライブラリがバージョンアップされず、C++11 辺りから使えなくなってしまいました。そも、以前から作者はもうメンテナンスしておらず、Mozilla が確かメンテナンスをしていたんだったっけ…ここ嘘かも。

Mozilla(の開発チームの一部)は、言語処理系のプラグインとして静的解析ツールを実装できないか、と考えました。結果、生まれたのが gcc compiler plugin とコンパイラプラグイン Dehydra です。が、gcc の AST(抽象構文木)は、ツールを作るには位置情報等があまりにも不足していました。少し話がそれますが diagnostic を大切なものとして設計された clang の AST は、その辺りかなり配慮のある設計がされています。また、gcc の mangling のタイミングが安定しておらず、コンパイラプラグインにわたってくるタイミングで何故かシンボルが mangling されていたりいなかったり、といったバグもありました。そもそもコンパイラプラグインなんて想定せず開発されていたのでバグともなかなか言いづらいのですが。

自分が見ていた範囲では、上述のようなことを Mozilla は行っていました。clang もコンパイラプラグインの仕組みを持っていたのですが、Mozilla は「代替言語を作る」道を選びます。それは勿論 C++ を捨てることを意味します。

結果として誕生したのが Rust です(Cyclone の話は割愛します)。大規模 C++ プロダクトのコードを置き換えられるような言語でなければいけませんでした。そして、Rust は十分にそれを果たせているように思います。

「スマートポインタが生まれるまで」補足

C++ には GC が存在しません。少なくとも今は。生のアドレス値をポインタ型を使って扱うことができます。逆にいうと、GC がやってくれる「ゴミ捨て」を(GC には compaction 等の仕事もありますが割愛)自分でしなければならない、ということです。GC のない言語を利用したことがない人には想像がなかなかつかないと思うのですが、常にリソースの管理をしながら本来の処理も記述しなければいけない、というのはかなり大変です。

大変ですから、その仕事を楽にしようと仕組みが作られます。元記事で言及されている unique_ptr 以前から、C++ にはスマートポインタが存在しました。様々なライブラリが独自に色々作ったりしていましたが、標準ライブラリからは auto_ptr が提供されていました。これは、Rust に同じく(Copy trait の話は割愛)代入演算子が move となるようなポインタ、のように振舞うクラスでした。しかし、代入演算子が通常はコピーとして使われていた当時、auto_ptr の semantics には多くの開発者が混乱させられました。結果として auto_ptr は「使うな」と言われてしまいました。使うなと言われてはしまいましたけれど、この頃から move semantics は(標準ライブラリレベルで)存在したわけですね。

言語サポートが入ったのは、元記事にある通り C++11 ですが、それ以前から Boost ライブラリ等でもスマートポインタやスレッド(スレッドは所有者が一人でなければならないリソースなので、move が必要です)に対する move のサポートはありました。また、lifetime(寿命)の概念についても Boost scoped_ptr や shared_ptr の頃からライブラリレベルで示されていました。認知度は…兎も角…

「Rust の言語機能」補足

どの機能も、何かしらの既存の言語に存在するものですが、C++ にはなくて辛かった、みたいな機能ですね。一応書いておくと、generics と template は似ているようで全く異なる言語機能です。

結局何が新しくないのか

lifetime や move semantics は C++ に元より存在する概念でした。そも、言語のサポートのあるなしに関わらず、raw pointer を扱う言語であれば、意識しないといけないものです。皆さんも C でこんなコードを書いた経験があるのではないでしょうか。

struct string {
  char *ptr;
  void (*free_fn)(char *ptr);
};
void free_string(char* ptr) { free(ptr); } // malloc などで生成された char* のための開放関数。
void do_nothing(char*) { ; } // リテラルなどで生成された寿命を持たない、もしくは寿命がスタックに管理されている char* のための何もしない解放関数。

デストラクタによる自動解放こそないものの、これはまさしく C++ のスマートポインタにおける custom deleter ですね。結局言語サポートがあるかないかだけで、C だろうが C++ だろうが同じことをやるわけです。ちなみに、このような複数の lifetime を同時に扱う仕組みは、Rust もちゃんとサポートしています。Cow trait だっけ、違ったらすいません。

長くなりましたが、つまり新しくないのは、lifetime や move semantics の概念です。C++11 以降も加えると、move semantics の言語サポートも新しいものではありません。

結局何が新しいのか

消去法で残ったの出すだけです。新しいのは lifetime と linearity の言語サポートです。

Rust では変数の寿命をコンパイラがチェックしてくれます。それは参照も同じです。C++ の参照はごく稀に「この参照触ってる間に死んだりしないよな…」と心配になることがあります。ownership を意識してコードを書いていれば大丈夫なんですが、外部ライブラリとか使ってると信用できませんからね…Rust の借用は、lifetime がコンパイラに管理されている参照です。参照が生きていることはコンパイラが保証してくれるので、安全に利用することができます。

また linearity、雑にいうと変数が一回しか使われてないかどうか、触っちゃいけないもの触ってないか、もチェックされます。これで死んだオブジェクトを触ってアチャーという事故も静的に検出し、防ぐことができるようになります。

Rust の新しい部分は、結局の所メモリなどのリソースを管理する上で、C++ で足りなかった、あって欲しいなと皆が思っていたものと言ってしまっていいでしょう。

C, C++ の話多すぎてわからないんですが

Rust は最初に書いた通り、MozillaC++ で書かれた巨大プロダクトのコードを置き換えられる言語でなければいけませんでした。C++C++ なりに色々頑張っていたので、Rust はそこから良いもの(lifetime, move semantics)を取り出し、足りない部分(lifetime と linearity)を補いました。のでどうしても C++ の話を出さざるを得ません…というかぶっちゃけ Rust って C, C++ 使いがやったーという気持ちになる言語だと思うので、そうでない人に良さ伝えるの、無理ですねこれ(諦念)。

一応諦めずに説明頑張ってみよう。GC のある言語でも、不要になったらこのメソッド読んでね、というようなメソッドを持つクラスはあります。あれを適切なタイミングで呼ぶの、自明なようで大変ですよね。不要になったと思ったら別スレッドでまだ使われていたとか、そういううっかりをやったことがある人はそれなりにいるんじゃないでしょうか。そういったことを常にやらないといけないのが C, C++ で(C++ は頑張ってますが)、それを全力でサポートして、危険なコードにめっしてくれるのが Rust、でどうでしょうか。やっぱり駄目か。

で、全力でサポートしてくれるので、リソース管理を GC に任せっきりで生きてきた人が Rust を書くと、大抵変なコードができあがるわけですが…まあ当然ですよね…

まとめ

話が散漫としすぎたのでまとめます。

  • Rust の lifetime の概念や move semantics の言語サポートは C++ 等で以前よりあった、特別新しいものではない。
  • Rust の lifetime や linearity の言語サポートは(研究用の言語とか除けば)新しいものである。
  • Rust の motivation に C++ が絡むので、C++ 知らないと Rust の嬉しさを真に理解するのは難しい。
    • C++ での lifetime の概念や move semantics の言語サポートですら難しいのに、それにまだ言語サポートが増えるんだから当然のこと。でも、安全なコードを書くためには必要で、(C++ を書いていた)皆が望んでいたもの。

うーんやっぱり Rust の良さ、新しさを C, C++ を書いてこなかった人たちに説明するのって難しいですね…雑におわります。

追記:みんなが望んでいたものとか書いてるけれど世の中にはスマポ使わない派とか free しない派もいるので多様性です。

近況

12 日に大事な打ち合わせがあったのだけれど、気圧による体調不良で欠席の連絡もできずに(かろうじて DM 送ってくれた h 君のおかげでほぼ無意識に何か DM 返事してて体調不良だということは伝わったっぽい)死んだりした。

昨日は起床失敗してお薬切れて死にかけ状態から、気合いでお薬マシマシしてなんとか回復後即仕事→ダメージ回復しきってなくて今日またダウン。無理はよくないですね。まあでもそこまで重くないので夕方には落ち着くかな…

受託している案件が一件、話進めてる案件が一件、生活保護が未だに受けられていなくてこれの対応もしないといけない。三つも抱えていることになる。
生活保護の件は NPO の人にあとはメールで~と言われて一か月くらい放置されて、reminder メールしたら忘れられてたっぽくて返事きた。同伴するので役所にいくなといわれてたので、当然進展はない。働いてるのにまた借金するはめになりそうというか多分なるので相談中。厳しい。

フリップフラッパーズがとても面白かった。スタッフトークショーにも行った。体調的にも金銭的にも行ってる場合じゃないんだけれど、何のためにわざわざ生活保護やめて働きだしたかって、色々あるけどちゃんと楽しく生きたいねということなので、行って良かった。
体調は兎も角、精神的にはまあ安定していると思う。前の案件と違って一歩引いた立ち位置から見てるからかな。どう考えても炎上案件だーと思いつつ、契約通りメインのギョムーにはバグ対応とか以外あまり手を出さない。自分が頑張れば色々一時的には改善できるとわかっていてもやらないというのは結構しんどいんだけれど、まあ契約内容が契約内容だしと無理矢理納得する。それでもこの前請求書作るために働いた時間計算したら、働きすぎてたんだけれど…

大変ですが頑張って生きていきましょうというようなあれです。仕事その他でいっぱいいっぱいで、最近正規言語のお勉強ができてないのでワオワオワーという感じ。他にも数学の本(今度は確率論だよ、これなんで学ぼうと思ったんだっけ。SVM について survey してたからちょうどいいけど)頂いたのに。忘れないうちに正規言語の pumping lemma のまとめ書かないと。あと去年読んだ論文のうち面白かったのも紹介したい。

何にせよ焦らずやっていきましょう。お金がないどころか赤なので、生活保護の件だけは焦りましょう。貰えるはずの 60 万くらいを貰ってないんだよなあ…焦りましょうっていうか、役所に水際作戦されて、NPO の人に相談したら忘れられて、なんかもう誰を頼ればいいんだ状態なんですが。reminder 送ったらちゃんと対応してくれたし、あとは同伴で役所に GO すれば…

そんな日々です。

年を越したりなど

した。
実家にも帰れなかったし、年越し感が殆どない。めでたさを感じられていない。今度神社へいっておみくじでも引いて来ようと思う。おみくじは、好きなわけじゃないけれど、正月関係なくたまに引く。人生ガチャ。

2016 年は色々と失敗だった。失敗というか、甘かったし、災難だった。病人がリスクを抑えつつ働いていくためには…みたいなことを、きちんと考えないままふんわりやっていたのがよくなかった。そもそも個人事業主になった経緯が経緯なので、仕方ない気もする…好きでなったわけではない…現状他に選択肢もないので今後も暫くは個人事業主として働くことになりそうだけれど…暫くが具体的に何年なのかはわからない。先のことは、分からないことばかりだ。

昨年は、6 月末にお仕事の契約切られてから、二か月程休憩期間ということで休んでいた。実際前のお仕事で結構疲れていたので、一か月くらい休むのは順当だったと思うけれど、二か月は休み過ぎた。ここで休まずに、きちんと次のお仕事探しをしていれば、貯蓄が尽きる前に仕事が見つかっていたかもしれないし、見つかっていなかったかもしれない…単に運な気もする。運だ。病人が仕事を取ってこれるかどうかというのはほぼほぼ運で、ボクが一所懸命お客さんの所に足を運んで売り込んでとかやっても、基本的には大体ダメで、ダメでというかダメだったんですけど…まず自分の病気の都合でリモートワーク必須という自分の条件が厳しすぎる…それが、今受けてる案件のようにサクッと決まったりもする。あまりにも運。
色々あったけれど、一つ言いたいのは、自由な働い方~とか謡っている社の殆ど、少なくともボクが行った社の全ては大して自由ではなかった。当たり前だけれど、社会は病人に厳しい。社会は普通に健康な人間に最適化されている。合理的だし、正しいとは思う。しかし今のボクは病人なので、困る。
あと、ボクはフルタイムで働けない。フルタイムで働けるなら普通にサラリーマンに戻る。時給単価の安い仕事なんて受けて居られない。時給単価安い仕事せっせとやって貴重な体力を失うくらいなら、大して貰えない生活保護でも受けつつ仕事を探したほうがましだ。問題は生活保護受給額で仕事探しって交通費すら厳しいということなんですが…いやほんとに…
高い時給単価で案件を受けるには自分のバリューが一定高くないと、そういった案件は受けることが難しい。これも運な気がするけれど。あまり外面を保つためだけに何かやるみたいなのは好きでないので難しいところだけれど、個人事業主で、自分という存在がある種のブランドで、自分でお仕事取ってこないといけない以上は、その辺も考えないといけない。一番分かりやすいのは OSS プロダクトに contribution したり自分で何か作ったりだと思うのだけれど、ボクはそういった行為に全く興味がない。仕事で使ってるものに仕事の時間外にちょっと contribution するくらいはやっていった方がいいのかもしれない。それで仕事で使っているライブラリなどが改善されたりすれば仕事もしやすくなるし。一番いいのは業務として contribution することだけれど。
というか実際に仕事ができるかどうかなんて正直 github で草生やしまくってるとかと殆ど相関ないと思うんだけれど、どうなんだ。まあ、どうでもいいか。ボクには関係ない。話せる範囲でお仕事の話をできればいいと思うんだけれど。
まあしかし、どんなに自分は優秀ですよとアピールしたところで、精々一日四時間ぐらいしか安定して稼働できない、リモートワークでないと働けない病人ですよといった途端にバリュー一瞬で下がるし、どうしようもない気もする。ウムム。
長くなったけれど、急にお仕事なくなって困った~みたいにならないようにしましょうということです。去年はそうなった。今年はそうならないようにしたい。
あと、これは去年からわかっていたことだけれど、もう正直安定稼働が見込めない人間は開発ガンガンする系のプログラマとしては価値が圧倒的に低い。ので、案件も単に何か作るみたいなのを受けるのは多分お客さんにとっても自分にとっても損で、そうではない何かがいいはずで、じゃあそれって何なんだという部分を、もうちょっと考えていきたい。必要ならその辺の学習もしないといけない。

長くなった。次に生活保護。前述したように 11 月に貯蓄が尽きた。ガルパン BD とかグッズとか買いすぎたせいでは?といわれると、まあそうなんだけれど、買っていなくても、どの道 12 月には尽きている。大体自分が稼いだお金でアニメの BD も買っちゃいけないんだったら、もう何のために働いてるのかわからなくなってしまう。
ケースワーカーによる(意図的なものか単にケースワーカーに業務遂行能力がなかったのかは謎、恐らく両方)水際作戦を受けて、本来 11 月に受給できていたはずの生活保護が、今も受給できていない。NPO に相談したところ(実際に相談窓口に依頼してから対応してもらえるまで二週間以上かかった、それだけ相談が多いのだろうとかg萎えると闇)、ケースワーカーの対応が違法なものと判明したため(少なくとも法的に定められていないことを言われているなということは分かったので相談した)、NPO の人とカチコミにいきましょう、ということになった。行くまでは話は進めないでください、といわれてそれを守っているので、未だに受給できていないのだけれど、いい加減貰うもの貰えないと、貯蓄がなくなってから早二か月と少し、当たり前だけれど困っている。今のお仕事の収入が発生する方が早いみたいなことになりそう。全く笑えない。
ややこしいのは、本来 11 月に受給できていれば、12 月のアパートの更新料も自分が払う必要はなかったし、そのために余計に借金する必要もなかったという部分で、その辺どうしましょうね、というところで電話での相談は終わって、以後はメールでやり取りしましょうとなったのが先月の終わりくらいだった気がする。メールはまだ一件もきていない。アドレス確認のメールくらい欲しい。メールアドレスは口頭で伝えたので、間違えって伝えているかもしれないけれど、その時はまた電話がくるだろう…住所から電話番号から知られているのだから…順当に考えれば、単純に年末年始で NPO の人もお休みなのだと思う。NPO の対応してくれている人がどういう人なのかがまず分かっていない。NPO の人にまで放置されたらもう知らない。この一件のおかげで人間がどんどん信用できなくなっている。
ところで水際作戦はよくある話だと聞いていたのだけれど、NPO の人に詳細伝えたら、急に声のトーンが深刻になって、違法ですね…みたいになったので、実際に NPO にそういった事案が相談されることは少ないのかもしれない。泣き寝入りが多いのか、生活保護受ける人間の殆どなんて、基本的には高齢者なので(少なくとも、うちの区の生活科で年寄り以外を見かけることなんてあまりない)、年金で我慢とかそういう感じになるのか。それとも破滅するのか。
なんにせよ、病気を患ってはいるが復職、就労の意志のある 20 代の若者(そう、まだ 20 代だ)に水際作戦は辞めて欲しい。いやそうでなくても違法だし辞めろよという話なんだけれど…年寄りみたく、他にも年金とか貰えるなら分かるけどさ…他に貰えるものなんて何もない若者に対してやることじゃあないと思うんですが…何なのだ…社会は厳しい。

病人生活六年目だけれど、病気背負いつつ個人事業主始めてからは一年なので、まだまだこれからですね程々に頑張りましょう、ということで、終わりです。生活保護問題今月中には解決するといいけど、今月忙しい(今請けている案件以外にも営業続けているお客さんがいるのでその諸々)ことが既に確定してるんだよなあなんなんだほんと…

Scala Advent Calendar 2017 について & sbt console を -Xfatal-warnings & -Ywarn-unused-import で使う

この記事は Scala Advent Calendar 2016、25 日目の記事です。

今年は Scala Advent Calendar が二か所、Adventar と Qiita の二つのサービスで開催されました。今年も、という方が文脈的には正しいかもしれません。

http://www.adventar.org/calendars/1492

http://qiita.com/advent-calendar/2016/scala

文脈としては、毎年どっちにしようか、と gitter の scalajp/public 等の Scala のコミュニティの一部で悩んでいるうちに、両方で作られちゃって、さあどうしよう、まあいいんじゃない?みたいになる、という流れです。

とりあえず 2016 年分について、2016/12/31 現在の様子を画像で残しておこうと思います。

Adventar

f:id:lyrical_logical:20161231161100p:plain

Qiita

f:id:lyrical_logical:20161231161013p:plain

Scala は本当にここ数年で知名度が上がりました。とはいえ、当然二か所で開催すれば 50 日分を埋めるのは大変です。

Adventar は登録者が全く足りていません。まだ書かれていない日付もありますね。

Qiita はサービスが SEO 頑張ってることもあってか(ご苦労様です)、登録者は埋まっています。が、まあこれから乗っ取るんですが、最終日である 25 日他、数日分が書かれていません。
ちなみに最終日を乗っ取るのは、単純に、来年カレンダーを(特に Qiita 側で)作る人の目に留まりやすいかな、というだけです。他の日でも、Adventar の空いてる日でも、なんなら Advent Calendar として書かなくてもいんですが、一応。

年が変わるまで(あと 7 時間…)、もしくは年が変わってから記事を遅れて書かれる方もいるかもしれませんが、矢張り年内には埋めたいですし、今の状況はとても悲しいものがあります。他の言語や何らかの Advent Calendar が穴あきだったり記事が書かれていなかったりして残念だなと思ったことはありませんか?Scala もそうなっているのが現状です。

サービスの機能を使って Advent Calendar を作ることなんてユーザの自由だ、という主張もあると思いますが、Scala という名前を冠している以上は、コミュニティの一員である、そうであると見做されることを意識してもらう必要はあると思います。

ということで、来年こそはしっかりカレンダーを埋められるように、本来の Advent Clanedra のように毎日ワクワクできるように、カレンダーを作る人はカレンダーを作る前にコミュニティに相談をするなり、コミュニティはコミュニティで先手を取って両方作っておいて片方のサービスからもう片方のサービスへ「今年はこちらのサービスで開催しています」とフォワーディングして対応をとるなり(案の一つです)、何らかの手を打つべきだと思います。

(これは余談ですが、Scala という言語は知名度が上がった割に形の定まったコミュニティというのがないので、このようなことになりやすいのかなという気がします。そういうコミュニティのほうがいいのかどうかは別の話なので、この話はここで終わりです)

Scala 2.12 のリリースは当初の予定より本当に本当に大幅に遅れましたが、それでもちゃんとリリースされました。2017 年はライブラリの 2.12 対応も進み、本格的に Scala 2.12 が使われていく年になるのではないかと思っています。躍進の年にしたいですね。
実務での採用例も一気に増えて…るんじゃないかなあ。自分の話になってしまいますが、今年夏から冬にかけて、色々な会社へお仕事の相談をさせて貰いに行ったりしたのですが、割とどこへ行っても ScalaScala でした。別に自分は Scala で営業してるわけでもないので、行く先々で ScalaScala 言われているといった感じでした。皆 Functinal だとか Resilience だとか reactive だとかに騙さ…なんでもないです。FP は fun & functional だし Resilience は大事だし reactive はサイコー、いいね?

技術的な話がないけれど、Qiita 外の記事だから大丈夫かな?良いお年を!



…やっぱり何かちょっとした Tips 位は書こう。

Scala の警告は、基本的には probably bug です(設定で警告増やしたりできますが)。ので、"-Xfatal-warnings" コンパイルオプションを付けている人は多いと思います。
この時に困るのが、sbt のプロジェクトでそのような設定をしている場合、特によくあるのが "-Ywarn-unused-import" コンパイルオプション等と組み合わさって、sbt の console タスクが使い物にならなくなることです。
これを回避するには、sbt の scalacOption キーに以下のような変更を加えることです。

scalacOption in (Compile, console) -= "-Ywarn-unused-import"

これで、Compile スコープの console タスクにおける scalacOption からは "-Ywarn-unused-import" が取り除かれ、sbt console も無事使えるようになります。万歳。
この話は一応 stackoverflow 等で昔から広まっている知見なのですが、stackoverflow と違う点としては、シーケンシャルな値を扱う SettingKey に対して "-=" メソッドが使えるように sbt が改善されたのを受けて、記述がスマートになっている、という点でしょうか。逆にいうと、この設定(コードですが)が通らなかったら、それなりに古いバージョンの sbt を使ってるということなので、バージョンアップを考えましょう。
これで技術記事としての体裁も保てられるかな?では今度こそ、良いお年を!

Scala のデフォルト引数の評価タイミングとフリップフラッパーズ

この記事は Adventar の Scala Advent Calendar 2016 の 25 日目の記事です。遅れてすいません。まあ登録したのが 25 日だったと思うので許して欲しい。あと忙しかったり体調崩したりしてた。

カレンダーの占めなのでドカンと何か書くべきだし、書きたいことも色々あるのですが、Scala にフォーカスして、となるとぱっと書けるものはないので(ぱっと書けないものはあるけど今は時間がない)、適当にクイズでも。Scala パズルです。

www.shoeisha.co.jp


というわけで早速問題。以下のコードを実行すると、何が出力されるでしょう。

def f(x: Int = { println("flip flap"); 0 }) = x

f()
f()

特に難しくはないです。いきなり正解というのもなんですし、今期の面白かったアニメイションの宣伝でもします。

今期はなんといってもフリップフラッパーズでしょう。すっかり原作付きアニメが増えた昨今ですがオリジナルアニメです(今期はオリジナル多かった気がする)。シナリオ構成が綾奈ゆにこさんだったので一応チェックはしていたんですが、完全にブラックホースでした。ちょうど今日、一部の地上波で最終話が放送されます。

www.flipflappers.com

この記事を見ている頃にはもう放送は終わっているでしょうが…良かったですね!ウェッブで、正確には abema TV で明日最終話見ることができます。なんと最終話放送前に、1 話から 12 話までの一挙放送もあるので、まだ見ていないという方にも優しい構成です。一挙放送の後に WEB での最速配信で最終話という完璧な構成。やったぜ。

abema.tv

話としては、所謂 Girl meets Girl な SF です。
女の子が突然現れた女の子に振り回されて冒険譚します。六話までは深く考えずに見ましょう。毎話毎話、テーマの違う異世界に行って冒険譚をするのが基本的な流れです。うさぎ回(?)あり、サバイバル回あり、ライバル登場回あり、ホラー回あり、シリアス回あり…たまに「あれ話とんだ?」みたいな感じになりますが、後半回収されるので気にしなくていいです。後半、箸休め的にロボ回もあります。一応ある登場人物の重要なターニングポイント回でもありますが。
繰り返しになりますが六話までは、兎に角深く考えずに見ればいいです。それだけで楽しめます。一話完結物見てるつもりで見てればいいです。良く動くし背景も劇伴も演出も凝ってるし、勿論お話も毎話良く出来ています。六話なんて違うアニメをみてたのかな?という感じになると思います。
七話から徐々に風呂敷を畳んでいく流れになります。これを書いている時点で最終回を見られていないので、どういう結末を迎えるのか分かりませんが、とりあえず 12 話までは毎話面白く見ています。

兎に角視聴しましょう。というわけで、そろそろ答え合わせです。出力結果は…

flip flap
flip flap

flip flap flip flap。簡単すぎましたかね。エンディングのサビの歌詞の一部です。もうフリップフラッパーズの話はいい?そんなあ…

デフォルト引数は、メソッド呼び出しのタイミングで毎回評価されます。そもそもデフォルト引数に副作用を伴うような値を置くなという話はありますが、ちょっとしたクイズでした。詳細は SLS 6.6.1 参照。

なんでこんなクイズを出したかというと、Python がデフォルト引数を関数定義時に評価して使いまわすことをふと思い出したからでした。ろくに書いたこともない言語の pitfalls なんてなんで知ってるのか、なんで思い出したのか全く意味が分かりませんが、人間なんてそんなものです。まるで一貫性がない。記憶は揮発性。ろくなもんじゃない。

プログラミングする上で「いつ何が評価されるか」を正しく知っておくことは重要です。例えば、有名な話ですが by-name parameter は call-by-need ではなく call-by-name に評価されます。

def twice(f: => Unit) = { f; f }
twice { println("flip flap") } // "flip flap\nflip flap\n" が出力されます

あとは、無名関数だと思って書いた部分が、実は無名関数内で評価されずに、先に評価されちゃっていた、とか。よくあるやつです。akka-http のドキュメントに丁度よい例がありますね。

val a = {
  println("MARK")
  complete("yeah")
}

val b = complete {
  println("MARK")
  "yeah"
}

`{ }` は無名関数とは関係なく、単なるブロック式だというのは Scala 初心者、初学者のはまりがちなポイントの一つだと思います。`{ case => ... }` のようなブロックが Function ないし PartialFunction が期待される文脈で記述されているとよしなに変換されるとかいう、なんでそれ文法レベルで無名関数にしなかったんだよという無駄に複雑なルールもありますしね。誤解しやすい。

他に評価タイミングネタだと shapeless の Lazy トレイトとかあるんですが、こいつはただの call-by-need な semantics を表すものかと思いきや、implicit parameter の解決に絡む闇があり、これだけで記事一つ書ける奴なので…あれ、じゃあそれについて書けばよかったんでは???

ということで、そろそろ TOKYO MX で放送が始まってしまうのでおしまいです。
Scala Advent Calendar にかこつけてフリップフラッパーズ宣伝したかっただけです、すいません。

今年中に記事書くのはこれが最後かな。良いお年を。来年頭は 2016 年に読んだ面白論文紹介記事とかになると思います。

「「What Is Functional Programming? に対する反論」を読んで考えたこと」に対する反応

mandel59.hateblo.jp


何か一々記事まで書いてもらったので、一応…

関数の外部から書き換え可能で、関数の内部から参照可能なmutable変数は、関数への入力として使うことができる。(このような入力を副原因という。)

副原因という、特に有用性のない(私感です、詳細な理由は後述)term をこれ以上使うのは止めて欲しいです。正直元記事に対する一番強い気持ちはこれです。
関数の純粋性を副作用(side-effect)を引き起こす(cause)もの、というと長いですが、前回の記事から参照した中野先生のスライド見て貰えば分かる通り、そもそも元記事で副原因(side-cause)と呼んでいるものは、「定義次第では」副作用に含まれます。

www.slideshare.net

前回の記事でも言った通り、ページ指定したリンクを貼ってもそのページは埋め込めないようなので 27 ページ、また 27 ページで参照されている各種 url を参照して下さい。

関数への入力として使うことができる。

関数への入力は、数学的にもプログラミング的にも引数を指す語として定義されるべきでしょう。認識の相違ですね。ここの認識に相違があったこと初めてなんですが。
元記事や id:mandel59 さんの主張通りに入力を引数以外も含むものとして定義していいなら、例えばプログラムを実行する時間であるとか、そういったものまで入力と解釈することが可能になるのですが、それでもいいならどうぞ、というところです。
多角的に物を見ることは大事ですが、定義が複数あればうれしいかというと、そんなわけはないという話です。腕時計を二つ付けたら、どちらを正確な時間をどうすべきか困りますね。比喩として昔ウェブ上で詩人をしていた人のポエムを使わせていただきました(ランダムにポエムが表示されるので見たい場合は表示されるまでリロードしてください)。

ここで言っている「環境」って、何を指しているんでしょうか?

環境という語は明確な定義をもってして使ったわけではありません。これはプログラミング言語の仕様として環境が定義されているものもあればそうでないものもあるとかそういう事情です、というのは今取って付けたもので環境も通じない人間いないでしょという気持ちで書いてただけです。ということで「一般的によく言われる環境」くらいの意味です。それでは足りないといわれるなら、R5RS の 14.4 辺りの定義に従ってください。

こういう場合も「暗黙的に環境内の変数を参照する」に入るんでしょうか?

前述の R5RS に従えば入ります。入らない「環境」の定義って存在するんですか…?side-cause みたいに作ればその瞬間から存在するでしょうけど…

このくだりはほとんど意味が分かりません。

すいませんがここが分からないのは完全に Ryuusei さんの勉強不足なので勉強してください以外いうことないです。環境に対する理論的な理解も実行時の実際の挙動の理解も足りてないように思います。もしくは理解しているけれど理解していない体で書いてる?いやなんというか、ここ理解できないレベルの人に何か言われたりしないだろうという気持ちがあったので、正直「意味が分かりません」と id:mandel59 さんに言われると全く思っていませんでした。

そもそも書いてもいないことを突然やりだしたように見えます。

一例目は「環境」を言語から触れるようにした例なので、環境の話の文脈からのコード例としては妥当だと主張したいです。
二例目はやりすぎました、無視していいです。

揚げ足取りに見えます。

「このコードに副作用が生じる可能性がある個所はどこでしょうクイズ」の定番なので、副作用の話をしておいてここスルーはないです。せめて前提に陽にその箇所には副作用はないと書いてもらわないと困ります。
これは理論がどうとか抜きに「実務的に」困ります。この関数は純粋ですよとかいって高階関数書いておいて渡される引数の関数が純粋である保証、もしくは precondition をドキュメンテーションなどしていないコードとか書かれたら、普通に困ります。本当に困るので三回書いておきます、困ります。
まあ正直揚げ足取りですと認めてもいいです、どうでもいい。ただ「より注意深く観察すると、ここにも副作用が潜んでいる可能性はありますね?」ということが、ボクの記事を読んだ人間に伝われば、それでいいです。

この定義では、副原因を持たないが副作用を持つ、次のような関数を除外できないのでダメです。

すいません自明すぎて書き忘れました。これは自分の凡ミスです。暇なときに修正します。

ほぼ同じこと言ってますよね

その通りですが全く同じではありません。
まず大事な点として副原因という term は使っていません。純粋性を「副作用をまったく用いない関数型プログラムないし関数型言語を純粋」と定義し、副作用を「「式の値を計算して求める」(評価(evaluation)と言います)以外の動作」と定義していることから分かるように、副原因と呼ばれるものを副作用の一部と認めても良い(陽に認める形では書かれていないが、定義からはそう解釈することができる)ものとして定義しています。ということでまずここが違います。
第二に関数の「入力」について、元記事とは違い「入力を引数、出力を戻り値とする関数を考えることにより」とあるように、明確に関数の入力を引数として定めています。

こういう説明が簡単にできるようになるので、「副作用」と「副原因」を区別するのは有意義だと思います。

前述した通り副原因という term を勝手に作られるのに対して非常に否定的です、有意義だとは思いません。前述したように、副作用の定義の中には副原因と呼ばれるものも副作用とするものが既にあるので、単に混乱させるだけの可能性があるからです。

以上です。

発声練習

声帯というのは、人間がどんなに抑えても感情が出てしまう箇所だと聞いた。例えば、怒りを隠して平静を装って、それが他人には分からなかったとしても、波形には出るそうだ。人間の耳と、声帯のだらしなさを感じる。訓練している人なら波形にも出ないようにできるのだろうか。ちなみに記事の内容とは関係がない。

物凄く久しぶりにカラオケにいったら声がでなくなっていた。
声がでなくなっていたといっても本当に声が出ないとか、高い音が出ないとか、そういうことではなくて、声帯をコントロールする筋肉がまともに仕事しなくなっていた。

一般的に声は地声、裏声の二種類に分けられる。裏声は更に、声帯を開いた息の混じった裏声と、声帯を閉じた息の混じっていない裏声に分けられる。勿論声帯の開き具合で響きが変わってくる。
同じことが地声にも言える。しかしこちらは裏声よりも難しい。声帯の「閉じ具合」が適切でないと、きちんとした発声はできない。これは 1/f の~とかいう難しい話で説明できるんだけれど難しいので省略、まあ車のギアチェンジを想像してもらえばいい。3.25 速とかは存在しない。閉じ具合は一般に高い方に関して言われることが多いけれど、低い方にもある。けれど、とりあえず高い方について書く。これをミドルボイスとか最近は言うらしい。実際にはミドルボイスと呼ばれるものにもギアがいくつもあるのでボクはミドルボイスという語はあまり使わないようにしている。
上で書いた、声が出なくなったというのは、このギアチェンジが咄嗟に、つまり歌っている最中にできなくなったということ。各ギアで声を出すのはまだできた。できたといっても大分安定しなくなっていたし、母音によってはかなり酷いものだったし、各ギアで出せる音の範囲(音域だ)も狭くなっていたけれど…こうなると最近の比較的高い音の多い J-POP は歌えない。何も楽しくなかった。

10 月は営業に忙しくてボーカルレッスンに全く行けてなかったし(月謝…)、11 月には貯蓄が尽きるので辞めたので(まあすぐには辞めれないので実際に退会したのは 12 月なので、矢張り月謝…)、もう三か月近く「適切に」声を出すことをしていなかったのが恐らく原因なんだけれど、たかだか三か月でこれは酷いというか、今までそこまで早く劣化することなかったので、歳を感じる。もしくは病人生活が続いて筋力が下がり続けているのが効いてるのか。

お仕事決まったので二月からレッスン再開することは決めているので、今年中は忙しいので、来年になったら発声練習に週二か三くらいのペースでカラオケボックスへ行って、真面目にただひたすら発声練習しよう…と誓った。

ということで今日お仕事取ってきました。来週月曜からいきなりお仕事スタートです忙しい。

あ、でも今日カラオケ前に三時間ほど話し込んできたから普通に声帯周りの筋肉疲れてただけ説あるな…