呪文詠唱!F# #ML_study

ML勉強会 #2 - connpass

発表してきました。

要約

F#のコンピュテーション式を使うと呪文詠唱できます。 呪文詠唱自体に実用性はありませんが、やっていることは応用が効くかもしれません。

はじめに

突然ですが問題です。 

詠唱 {
  モナドは
  単なる
  自己関手の
  圏における
  モノイド対象だよ
  何か問題でも
  ``?``
}

このコードはF#的にvalidでしょうか?

正解

コンピュテーション式用のビルダークラスを適切に準備してあげればvalidになります。

中身

MLStudy2/Program.fs at 78359cf52503daa0c40cf5fed50a60dc89e5c9df · pocketberserker/MLStudy2 · GitHub

要するものは以下のとおり

  • コンパイルできるコードを制限するための型
    • 名前はなんでも良いので、今回はLine0とかつけてます
    • 別に判別共用体でなくても良いですが、シングルトンを作りやすいものが良いでしょう
  • Attributeから値を取得するためのヘルパー関数
    • カスタムオペレーター用のメソッドに指定したAttributeを取得し、そこから情報を抜き出します
  • カスタムオペレーターが定義されたコンピュテーションビルダー
    • カスタムオペレーターを使うことで、任意の文字列をコンピュテーション式のキーワードとして扱える
    • 中身はなんでも良い
    • 今回は呪文詠唱っぽくみえるよう、1秒ごとに呪文を出力している
    • Runコンパイル制限用に使っていた型の値を取り除く

コンピュテーション式は、展開規則に従ってビルダーに存在するメソッド呼び出しに展開されます。 この時、引数や戻り値の型を適切に実装すればあるオペレーターが呼ばれない限りコンパイルエラーとか、指定の順序で呼び出さない限りコンパイルエラーとなるようにできます。

今回のコンピュテーション式は呪文なので、カスタムオペレーターの呼び出し順序は固定です。 呪文は少しでも間違えると発動しない(つまりコンパイルエラー)なのは当然ですよね?

無詠唱

発表中は「無詠唱なんて許さない」と言いましたが、つくれないことはありません。 ビルダーにZeroメソッドを用意することで、無詠唱のようなことが行えます。

詠唱 { () }

https://github.com/pocketberserker/MLStudy2/blob/78359cf52503daa0c40cf5fed50a60dc89e5c9df/src/MLStudy2/Program.fs#L67

Zeroメソッドを定義する際の注意点は以下のとおりです。

  • ビルダークラスに定義されたカスタムオペレーター用のメソッドを全て取得
  • 上記実装はザルに作ったので実行順序が処理系依存ですが、詠唱順序をちゃんと固定したいなら、メソッド名をソートしやすいものにしたほうが無難
  • キーワード名とメソッド名は別でも問題無い
    • デバッグ時にわかりやすくするために名前を合わせることが多いとは思う

コンピュテーション式用のビルダーを生成できないのか?

ファイルから読み込んだ文字列群を用いてTypeProviderでビルダーを生成すれば、任意の詠唱を生成できるのでは、という話をしました。 残念ながら当日には間に合いませんでしたが…。

で、これについて昨日検証してみたところ、現場のコンパイラだと不可能っぽいという結論に至りました。

  • 必要なビルダークラスとメソッド、型までは消去型なら用意できる
    • 生成型は複数の型を生成できる気がしない…
  • 生成したビルダーのカスタムオペレーターがコンパイラにカスタムオペレーターだと認識されない

もしかしてコンパイラのバグだったらどうしよう。

https://github.com/pocketberserker/MLStudy2/blob/288cd0b25fd4cbc28c2dc80439bbc4a6a8a5992f/src/MLStudy2/Program.fs#L90

コードは公開しているので、検証したい方は好きにいじってください。

補足?

Indexed MonadをF#で用意できるのかは不明ですが、やりたいことは同じかと。 今回は時間がなかったのでごり押しでコードを書いてしまいました。

まとめ

言語機能を使って遊ぶのはとても楽しいです。

.NET Fringe Japan 2016の個人的な振り返り

dotnetfringe-japan.connpass.com

運営及び発表者として参加しました。

運営といっても、勉強会運営に慣れている方が多かったのでやること・やらないことが初期から明確だった気がします。 当日の懇親会周りの運営を手伝えなかったのは申し訳なく思いつつ……。

発表内容

not_fsharp_deep_dive.md · GitHub

発表内容はぎりぎりまで悩みつつ、気がつけば難産だったらしいkekyoさんチキンレースを繰り広げていました。

最初はコンピュテーション式のコンパイラ側の話にしようと考えていましたが、朝からそんな話を聞かされるのはつらいだろうと判断して早々に却下。 次にFSharp.Compiler.Serviceに挑戦しようかな、と考えましたが、別の発表でRoslynがでてきそうな気配があったのでこれも見送り。 では自分らしくどういうライブラリを作ったかについて話すか……と思いつつ、いやいやnueccさんの発表があるからなぁ、みたいな。

そうした紆余曲折があった結果、F# がどういう機能を持ち、持たず、その上で具体的に何が作れるのかについてしゃべることにしました。 が、今考えるとFSDNの話は削ってF#とC#関係について話した方が良かった感ありますね。

F#は今の所、.NET Frameworkや.NET Core、C#とは縁を切れない関係です。 おそらく今後もF#は何かしらの影響を与え、そして与えられる立場であることでしょう。 そういう意味で、F#のRFC機能について紹介しました。 RFCはディープではないはず……と思っていたけど、今考えたら「策定段階の企画書読む」って十分ディープでしたね……。

あと、発表の途中で".NET Framework 2.0ではTaskの独自実装が〜"と口走ったのは完全に間違いで、正しくはCancellationTokenSourceです。 大変失礼しました。

全体

今回の登壇者が同じ場所に揃う機会、ないのではないでしょうか。 Partitionの話とか、なかなか聞けないので面白かったです(なお理解度は怪しいorz)。 あとは、本当にマルチプラットフォームだなーという謎の気持ちが大きかったですね。

時間が長丁場だったのは反省点か……とはいえ、もう少し大きな会場で2部屋使えれば解決できるとは思いますが。 そういう意味では、継続するには協力者を増やす必要がありますね。 まぁ、来年のことは来年考えましょう(とか言っているとすぐ来年になる)。

終わりに

異端と呼ばれているイベントに登壇する機会をいただけて、かなり満足しました。

java-ja.OSSに参加

初のjava-ja参加でした。

java-ja.OSS - connpass

なんというかよく分からないテンションなので書きなぐってみます。

(遊びで書いた)コードの保管場所としてのGitHub

PC移行するときに面倒臭いしGitHubに置いてそういうリポジトリの通知を無視する勇気をもつ、とかそういう話が途中に発生していた。

これは私もある種同意見というか、私はもっとアレな表現として"GitHubはある種のゴミ箱"という考え方を持っている。 (会場でその発言したのも私なので謝る必要がある。アレな表現でごめんなさい)

私は仕事以外のコードはだいたい暇つぶしとか遊びで書いている感覚で*1、まぁPCを交換するかもしれないしなんか捨てるのももったいないので、どこかに退避させたいときにGitHubやBitbucketが楽だからpushするわけですね。 でまぁ、ここまでならアーカイブとかかっこいい言い方をすればいいのかもしれないですけど、他人が見るわけでもない、自分が見返すこともほとんどない、そんなコードが放り込まれている。 このただの投棄をカッコよくいう気は私はしないという話なだけです。

2015/10/06 13:00頃の追記

私にとっては、なので別に他の人にその定義を押し付けるつもりはありません。

GitHubでのコミュニケーション云々

したくないというか、英語できないマンとしてはno descriptionでpull request送ったり5単語以内に収めるとかよくわからないことしてます。

当日聞きたかったけど聞けなかったこととしては

no descriptionのpull requestが飛んでくるとどんな気持ちになりますか?

というのがあったが、まー本題ではないしいいや。

コミュ障とかパートナーとか

コミュ障というものにはいくつかあると思っていて、今回の場合だと

  • 見知った人にはそれなりに受け答えできる
  • 興味があること以外に関する会話の組み立てができない
  • (初対面だとだいたい「あー…」とか「えーと…」という反応になりがち)

とかそういう意味でのコミュ障ではないかと想像している。 だから勉強会運営などは知り合いメンバーで固めればそれなりになんとかなるし、ある程度定型文での受け答え+興味ある話での受け答えでなんとかなるのではないか、と。


パートナー云々の話は、パートナーという存在がいない身としては「ふーん、大変そうですね」以上の反応しかできなさそうです…。 いやまぁ、この自由こそがパートナーがいないことと引き換えの何かなのだろうとは思いますけど。

枯れたOSSの件

戦略的にはまだいくつかあると思いました。たとえば

  • 「私はつよい。ので、このOSSは完成している。疑問があるならここで質問どうぞ」と書く
  • 信頼度の問題?
    • 例えば定理証明支援器(Coqとか)で証明されたリポジトリに対して「最終更新が昔だから」とかの理由で使わないってあるのかな、みたいな

週末に自分のプロダクトを頑張る

目的があってやってるとこういうことになるのだなーということがしれてよかった。

目的なく気が向いたら自分のプロダクト触っているマンなのでたぶん縁のない話でしょう…。

自己鍛錬としてのOSS

なんか、つよいなーという感想(小並感

前述の通り私は休日は暇つぶしととか気が向いたらコードを書いている面が強いので、たぶん筋トレ的な開発は向いていないだろう。 気が向かないのにやろうとしてもストレスにしかなりそうにないと言い訳しつつ。

プログラマとしてOSSと関わりながら生き残るためにとった生存戦略 - scalaとか・・・

そういえば、上記記事も似たような理由でつよいなーと思ったのでした。 まぁ、私はOSS開発者という括りには入っていないと思われるので生存できてないわけですが。

余談: 暇つぶし道具としてのGitHub notifications眺め

昔からmixiのなにかとか、Yahooニュースのコメント欄とか、twitterとかを数時間(長ければ丸一日)飽きもせず(かといって楽しむわけでもなく)ぼーっと眺めて人生の何割(?)かを過ごした身としては、ある意味GitHub notificationsは暇つぶし手段として良いと思っています。

ただリアルタイムに追っているわけではなく、メールで飛んできているnotificationを、時系列の新しいものから順に気の向くまま目的もなく眺め続けるだけなので、結果として役に立っているかどうかは不明ですね。 ザ・時間の無駄遣い。

感情とOSS(?)

目的あって開発している人はパワーが違うなと思ったり、というか感情爆発させたあとでもきちんとリカバリーできているのすごいなと思いました。 私だったら間違いなく後悔で2週間ほど引きずるので感情で動けない…。

独裁とOSS

仮にscalazコミュニティ崩壊の元となった方にLinus氏やDHH氏のようなカリスマ?(他に単語を思いつかなかった)みたいなものがあれば、ことなる結果を歩んでいたのだろうか。 いやでも、Scalaってそういう優しい(?)独裁者をなかなかみない気がするのでScalaというコミュニティ的に避けられなかった話なのだろうか?

*1:pull requestは例外

#TestingFrameworkMeeting を開催しました

発表資料やtogetterは以下にあります。

https://github.com/tddbc/TestingFrameworkMeeting/blob/master/links.md

久々にこの濃度のイベントに参加した気がしますね…。 今やってることに直接参考になる話とかも聞けたりしたので個人的には大満足でした。

というわけで熱にあてられたので記憶している範囲で振り返ってみます。

t-wadaさんの発表

「simplify, amplifyで何かお願いします」とゆるめにお願いしてしまって、あとあとこれで良かったのかと悩んでもいたけど、まーさすがt-wadaさんというか、最初の発表としていい感じに話を広げてくださった。

議論などの流れでアドリブ入ったり脱線したりしたのはなかなか楽しい展開だった。

Evolve slowly

私はてきとーに作ってはGitHubにポイ捨てするタチなのでそんなこと考えてなかったけど、確かにテスティングフレームワークは緩やかな発展のほうが良いというのには納得。 ただ、それで発展が阻害されてしまっては意味ないと思うので、適度な競合ライブラリはあっても良いのではないかとは思っている。

Runnerの挙動が全体的にバッチっぽい

  1. テストケースを収集して
  2. テスト実行して
  3. レポートを出力する

RUnnerとしてはこの流れが主流だけど、もっとincremental(?)にやれるのではという話を(たしかJUnit5の話の流れで)きいて、確かにこの部分はどの言語でもわりと胸中しているなと感じた。 そしてなかなか手を出しづらい場所でもあるよね…。

余談

シンプルな方向に作る人たちってどういう時にCoreに機能を追加するのだろう、と前々から思っていたけど、話きいたり質問して"Coreという存在はなく、小さな各ライブラリに依存性がある"という見方をするのが良い落とし所なのかなと個人的に結論付けた。

あとpower-assertが非英語圏で流行ってるというのに妙に納得した。

Goとテスト

tenntennさんの講演。 Goのテストに加えてGo文化の話も聞けて良かった。

標準パッケージとして色々揃っている

これは後方互換を重視する言語であれば強みだろう。 なにしろよほどのことがない限り公式がメンテするのだから。

ifとassertion

  • Goのtestingライブラリにはassertionがない
  • if文を書いてテストに失敗した時はErrorfなどを返す

というのに対して

  • assertionがぱっと見どこにあるのかわかりづらい

という返しがあったのは、私にはなかった着眼点だった。 個人的にはifもassertionもそんなに変わりない気がしているが、違和感ある人はあるのだろう。

あえて機能を少なくすることで何が起こるか実験しいるのでは

みたいな意見があった。 推測の域を出ないけど興味深い考察だとは思うので、今後を見守りたいものである。

Lint

Kuniwakさんの講演。 私は個人プロジェクトではあまり使っていないが、仕事ではお世話になっているので最近の動向なども含めて色々きけて満足。

"変数名のtypo単体テストで発見するのは遅すぎる"

静的型付け脳な私としては「それバックグラウンドでインクリメンタルコンパイルしておけば」と思わなくもないが、動的型付けだと確かにこの問題はあるのかもしれない。

省力化ツール

この話をきいて、かつてmzpさんが「機械的に調べられるものは機械が勝手に修正をコミットしてくれるまで行けばいいよね」的なことを仰っていたことを思い出した。

読み手のみの省力化だけでなく書き手の省力化も、というのが今後業界的な流れになってもおかしくないのではないだろうか。

Lintとテストレフームワークを共通化

Runnerを共通化するという発想は私にはなかった考えなので新鮮だった。 どのくらい新鮮だったかというと、翌日から F# と Scala の自作テスティングフレームワークにその機能を組み込めるか試して見る程度には。

ぱっと考えてみた限り原理的にはいけそうなだが、どこまでビルドチェーンを複雑にせずに組み込むかはちょっと考える必要がありそうだとは思ってる。

ASTにに含まれない情報はどうする?

  1. 具象構文木をlintの対象にする
  2. トークン列も組み合わせる

というパターンが存在するみたい(前者はやや実験的傾向がまだ強うそうに思うのだがどうなのだろう)。

余談

PythonでVimScriptのLint作ってます」「GoでLuaのLint作ってます」の会話が個人的にツボだった。

QuickCheck(という名のテスト合成 + Property Based Testing)

私の発表。 これまた脱線しまくるという状況になった。

power assertに反逆したい

流行にはあえて反逆したくなることがあるので、そういうことを考えていますよという話をちょろっとしていた。 時間があったらもっと話したかったけど本題ではなかったので泣く泣くスキップ。。。

テストの合成

ここで色々と脱線してた。

  • テストの合成とはなんぞや
    • 初出ではなく、おそらく昔からある考えだとは思うけど出典見つけられず…
  • テストが疎結合にならないのではないか?
    • 疎結合とテスト実行速度のバランス次第だと思っている
  • 話し損ねたこと
    • unitを引数に受け取りテストケースを戻り値とする関数 -> 副作用を内包する
    • 変数に束縛されたテストケース -> 副作用を持たない or 一度しか実行しない
    • このあたりは言語によるかもしれない…?要検証

エッジケースの話

  • だいたい人間でもわかりそうな部分のエッジケースしか発見できなさそう

これは一理あるけど、でも経験的に予想外のテスト失敗に遭遇したことがある身としては

性質自体を間違ってしまうリスクをどうやって減らす?

これは難しい問題だと思っている。 個人的には、

  • よくある事例から性質を引っ張ってくる
  • ミューテーションテスト
  • 最初はユニットテストで担保し、ある程度でいけそうだと判断したら入れ替える
  • エラー周りから攻める
    • エラー系は入力集合を作りやすいことが多いし性質も"エラーになる"で終わらせられるから

あたりだと思っているが、根本的打開策になっていないのが厳しいところではある。

これはこれでスキルいるね

性質を導き出せるかは個人のスキルによるので、慣れていないとチーム全員で使うのは厳しいのではないかという指摘(というか参加者の感想)。

これは指摘通り。 まぁ、最初はリファクタリングの際に導入するとかで慣れていくしかないのではないでしょーか。

Serverspec

mizzyさんの講演。 OSSに対する姿勢などもきけて良い学びがあった。

AssurerとServerspecの思想の違い

実装動機が異なるとここまで異なるプロダクトになるのだなーと。

なぜRSpec?

  • 強いこだわりがあるわけではない
  • 非本質的なことには振り回されたくない

非本質的なことに振り回されたくないはかなり同意。 とはいえ、絶対に振り回されないは厳しいと思うのでどこまで最小限にできるかどうかなのかもな、と。

応用的な観点

テストをインフラの方面にもってきた、かつ敷居を低くしたというのを実感できる発表だった。

雑感

  • ここでもUNIX哲学の話が
  • テストあまり関係ないけど、人気ライブラリ開発者のお悩み相談的な部分が観れたのはとても良かった
    • やっぱり苦労している部分*1はあるのだなぁ、と
    • 長期間メンテされてないリソースはどうしているの? -> コミットした人にping送ったりして、反応ないなら消す(ちょっとここ聞き損ねたのでこういうニュアンスだったか怪しいです…)
  • 若干java-ja OSS編先取りしてしまった感あるけど面白かった!

飛び入り発表

飛び入りでESDocやoktestの話も聞けて、大変参考になった。 この辺りは思うところがあったのでちょっとライブラリに手を加えたりしてみている。

懇親会での話

特に記憶に残っている話を箇条書きで。

  • 枯れた(安定した)ライブラリが最終更新で判断されるのはなんか違う気がする
    • GitHubのstarや最新コミットが目につきやすいので無意識・意識的に誘導されてしまう?
    • どの程度使われているかに注目できれば良いのかも?人気言語まとめとかもどこかの団体が勝手にやってるわけだし
  • 信頼問題
    • Python2からPython3に移行できない理由とか
  • 人は自分が使っている言語を擁護するように動く傾向がある
    • かつてJavaにclosureやinterfaceのデフォルト実装はいらないという一派がいたらしいが、今や彼らはlambdaやデフォルト実装を推し進めている
    • オフサイドルールを否定的にみるRubyistをみかけるわりにその人たちはcoffee使うよね
    • (個人的には数年経てば考えも変わるよねとは思ってるけどあの場で言い忘れてた)
  • DBセットアップのテスト
    • Serverspec的なものをDBにも応用できないだろうか
    • DB界隈とソフトウェア界隈の空気の違い?的な話
  • 懇親会費が余ったのでJUnitに寄付することにした
  • いつv1.0.0をリリースするか
    • あれもこれもとズルズルいってしまう
    • 対象環境が多いとどこまで対応してからリリースすべきか悩ましい
    • 最低限という区切りを設ける/締切駆動開発などで時限式にするとか

furiosaやawsspecの話もきけて満足。

次回やるとしたら

やるかわからないけどこの辺り題材にゆるっと平日夜にやれないかな(議論したい、聞きたいというそこの貴方、発表者探しを手伝っていただけませんか? or 発表者になりませんか?)

  • 1メソッド1アサーション
  • ドキュメントとテストの関連性
    • doctestの話がちらほらでたり、飛び入りでESDocの発表があったので、もっと深堀りしたい
  • power assert

謝辞

企画に関わってくださった皆様、発表者の方々、他のイベントと被りまくっていたのに本イベントに足を運んでくださった皆様に感謝します。 皆様のおかげで、とても意義のあるイベントになりました。

そしてmixiさんとKuniwakさん、朝早くから夜遅くまで会場準備撤収ありがとうございました。 とても気持ちよくイベントを行えました。

*1:というか心の葛藤?

#TestingFrameworkMeeting というイベントをやります

github.com

概要や参加方法諸々は上記リポジトリに書いてあります。

ユニットテスティングフレームワークや関連のあるものについて議論してみてもいいんじゃないかな、と思って企画しました。 (なお、ここまでこぎつけたのは企画を一緒に練ってくださったTDD Base Campの皆様のおかげです。いつもありがとうございます)

若干ハードル高めですが、濃いイベントなのは間違いないのでお待ちしております。

7月以降に開催するイベントの告知

こんにちは、もみあげです。

最近ブログではイベントの告知をあまりしていなかったのですが、今回はいくつか企画が走っているので紹介しておきます。

FSharp談話室(20) ゲストもくるよ!

F#談話室(20) - connpass

Yan Cuiさんの来日に合わせての開催です。 現状参加者がちょっと少ないので、Yanさんの twitter bioにビビッときた方はぜひお越しください。

関数型Scalaの集い

関数型Scalaの集い - connpass

昨年開催されたScalaz勉強会の範囲拡大版ですね。

こちらは発表者を募集しております。 (参加枠は埋まってしまってます…が、運が良ければニコニコ生放送があるかも?)

余談ですが、公開前の仮イベント名はわりとひどかったです。

関数プログラミング交流会

こちらは今のところ発表者のみ募集中です。

関数プログラミング交流会 発表者募集要項

枠以上の応募があった場合は選考方式のため、発表できない可能性も」ありますが、枠から漏れた方の参加枠はあらかじめ確保するのでご安心ください。

参加枠は後日募集開始となります。

関数プログラミング交流会(参加者用) - connpass

connpassにフォローブックマーク機能があるみたいなので、忘れそうな方はブクマしておくと良いかもしれません。

ちなみに、前日にはProof Summitが開催されるみたいなので、こちらにも足を運んでみてはいかがでしょうか。

#関数型なんたら という勉強会をやります(ニコ生もあるよ!)

2014年10月25日土曜日に関数プログラミング的な交流会(?)のような勉強会を開催します。

函数型なんたらの集い 2014 in Tokyo - connpass

なぜ1週間前のこのタイミングで告知記事を書いているかというと、二木ニコ生放送があることを伝えたいからです(ドワンゴスタッフの方々、ありがとうございます!)

函数型なんたらの集い 2014 in Tokyo - 2014/10/25 11:30開始 - ニコニコ生放送

当日見れそうにない方も、アカウントがあるならタイムシフト予約しておくと便利かもしれません。

ちなみに

この勉強会の発端は、だいたい毎年行われている"函数プログラミングの集い"が今年はないという話をきいてちょっと残念に思っていたところ、

「野良でやってもいいんじゃない」

という話をTLで観測したので、会場があればやりたいなーと思っていました。 そんなときに

Scalaz勉強会を開催しました - scalaとか・・・

この記事の最後のほうにドワンゴさんの会場の話が書かれていたことを思い出したので、ScalaMatsuriのときに相談した、という流れです。