fsugjp/publicというGitter roomについて #FsAdvent

この記事はF# Advent Calendar 2015の28日目の記事です。

gitter.im

本日はfsugjp/publicというGitter roomについて書きます。 前にも書いたけど、もうちょっと詳しく。

どういう場所なのか

roomの説明部分には下記のように書かれています。

F#関連についてゆるふわ会話する場所です。初心者の質問も歓迎。

もうちょっと具体的(?)なことを書くと、

  • 誰かが疑問を書き、誰かが答える(ヒントを出す)か一緒に悩む
  • ライブラリやコンパイラ、VS拡張のissueを引っ張ってきて紹介する
  • 雑談

質問に対するレスポンスはわりと早いですし、様々なジャンルの方がいらっしゃるので勉強になります。

これを機会に、ぜひroomで F# のことを尋ねてみてください。

F# 4.0で入った地味だけど嬉しい機能紹介 #FsAdvent

この記事はF# Advent Calendar 2015の26日目の記事です。

通常のアドベントカレンダーは25日までですが、F# 界隈では英語版が31日まで続けているのにあわせて31日くらいまでやるっぽいです。

4.0の変更一覧

下記のページを見るのがてっとり早いです。

F# 4.0 Status · Microsoft/visualfsharp Wiki · GitHub

重めの機能でデザインとか背景とかを知りたい場合は以下。

fsharp/FSharpLangDesign · GitHub

こっちはvNextの草案も含めるみたいですね。

地味だけどうれしい機能紹介

F# 4.0はF# 3.0の時と比べると地味に見える変更が多い印象ですが、着実に改善されています。 というわけで、今回は私が地味にうれしいと思った機能を簡単に紹介していきます。

nthが非推奨になりitemが追加

ListやSeqモジュールにはnth関数がありましたが非推奨になり、代わりにitem関数が追加されました。

nthにはListとSeqで引数の順序が異なる(Listのほうがパイプライン演算子に優しくない引数順序だった)という問題がありましたが、無事統一できるようになった形です。

F# 4.0でnthを使うと警告がでます。 VS 2015を使っているとnthはインテリセンスで一覧に現れないので注意しましょう。

units of measureが型変換なしでprintfできるようになった

このページの例を見ればどういう挙動なのか一目でわかります。

クラスのオブジェクト生成を関数のように扱える

xs |> List.map Uri

こういうコードが書けるようになりました。

StructuredFormatDisplayAttributeで複数のプロパティを利用できる

以下のように書けるようになりました。

[<StructuredFormatDisplay("My name is {First} {Last}")>]
type Person = {
  First: string
  Last: string
}

今までであれば、別のプロパティをわざわざ(型よってはこれだけのために)追加しなければならなかったので、楽になりますね。

isNull関数の追加

.NETライブラリをラップするときになんだかんだお世話になりそうです。 あとstringでもお世話になってます。

終わりに

ところで、色々なライブラリはいつのタイミングで4.0に移行するのでしょうかね…?

TypeProviderでコンピュテーション式用の型を生成してみた #FsAdvent

この記事はF# Advent Calendar 2015の25日目の記事です。

TypeProviderを使う

今までチュートリアルくらいしかTypeProviderは作ったことはなかったのですが、ようやく重い腰をあげて使うことにしました。

型プロバイダー(TypeProvider)のちょっとしたアレコレ - Bug Catharsis

ぜくるお兄さんの記事、とても参考になるので何回も読み直してます。

コンピュテーション式とTypeProvider

コンピュテーション式のビルダーは単なる型なので、TypeProviderの対象にできますね?

というわけで今回は、以下のことをやってみようということに。

これ一年半くらい前の発言なのですね…。

結論

できなくはないけど、できることが限られていてつらいorz

https://github.com/pocketberserker/ComputationExpressions/tree/56f5f9dee7ecfaf77fd11cb79c6532727232427a

このリポジトリのコードを読んでいただけるとわかると思うのですが、Generic MethodがTypeProviderで生成できない関係で単一の型でしかbindできなかったり、その関係でdo!が使えなかったりと、少なくともMonadTypeProviderみたいな汎用的なものは厳しい印象です。

逆に考えると、ジェネリックさえからませなければわりとやりたい放題できるということがわかったので、なんか色々と模索したいところです。

当分はカスタムオペレータの方向で模索してみます。

最近使っているScalaのライブラリ

これは Scala Advent Calendar 2015(アドベンター版) の4日目です。

3日目は、xuweiさんの ScalaからScalaPBというsbt plugin使ってProtocol Bufferを使う方法についてのドキュメントを書いている でした。 Protocol Buffer使ってみようかな…。

言い訳フェーズ

scalajp/publicというGitterのチャンネルで参加者を募っていたので軽い気持ちで参加したものの、ついこの間ネタを放出したばかりだったので思いつかなかった。

苦し紛れ…。

紹介フェーズ

注意事項は以下となります。

  • この記事を書いた存在はScalaを普段使いしているわけではない
  • 自作ライブラリは除外

Scalaz

  • 前提
  • 特に猫に移行する理由がないのでこっちを使っている

Shapeless

  • 他のライブラリとともに勝手についてくることが多い
  • 最近ようやく使い方がわかってきた、かもしれない
  • Scala.jsをサポートしている

scalaprops

  • 便利

scalacheck

  • scalapropsがリリースされる以前に作ったものはこっちでチェックしているので現役
  • Scala.jsをサポートしている

scalatest

  • 最近はscalapropsで完結するものばかり書いているのでなんともいえない
  • DiagrammedAssertions(power assert)は使いどころによっては便利

httpz

  • べんきょーとか思って使っていたら慣れた
  • 慣れると便利…かもしれない?

http4s

  • 実装を読んでみるとなるほどなーという気分になる
  • 最近は破壊的変更が以前よりも減った気がする
  • 猫に移行するのか見守る
  • プロジェクト頓挫しないよね…?

blaze

  • http4sのついでに使っている
  • なんとなく使っているだけで特に理由があるわけでもない

構文解析

  • その時々で気になったものを使っている

Argonaut

  • httpzがこれに依存しているのでこっちを使っている

twirl

  • まぁ、こっちでいいかなって

doobie

  • 学ぶ目的

scodec-bits

  • バイナリ操作はこれ以外の方法はあまり知らなかったりする…

scodec

gatling系

  • 代替がない?

まとめ

  • 仕事でないなら好みで選べば良いと思います
  • 仕事なら周りにあわせそう
    • なおこの記事を書いている時点でScalaを仕事で使ったことはない

SmlSharpContribについて

これはML Advent Calendar 2015関数プログラミングAdvent Calendar 2015の一日目の記事です。

えすえむえるしゃーぷって?

SML# - SML#のダウンロード

関数プログラミング交流会で調査した感じだと、知っている人は増えつつあるがユーザはまだそんなにといったところなのかもしれません。

SmlSharpContribとは

ざっくりいうと「準標準パッーケージを作ろう」みたいな感じでしょうか。

が現状で提供されている機能です。

「え、その型すら標準にないの?」などと言ってはいけません。

ライブラリを作るという話になった経緯

2015年の2月頃に、大阪の知り合いが仕事の都合で名古屋に来るということで何名かでご飯を食べに行きました。 そこでなぜか(話の流れは忘れた)みずなんとかさんとぶれなんとかさんが「SML#の準標準ライブラリが欲しい」と言い出し、何人かを巻き込む形で始動しました。

なんか開発止まってるようにみえるけど…

みなさんお忙しいですからね、決して興味がなくなったとかいうわけではないはず…ええきっと。

もみあげはなにをしたの?

パーサコンビネータJSONパーサなどを作ってました。 XMLパーサも実装しようとしていましたが体力切れで絶賛放置中…。

おわりに

SML#は楽しい(はずな)ので、みなさんもSmlSharpContribに貢献するという形でSML#を触ってみませんか?

"ValueWithName"や"Auto-Quotation of Arguments at Method Calls"を使って変数名や関数名を取得する #FsAdvent

この記事はF# Advent Calendar 2015の一日目の記事です。

Expr.ValueWithNameの話

以下のようなコードがあるとします。

let f a = <@ a @>
let hoge = "Hi!"
f hoge

これはどう表示されるでしょうか?

F# 3系までは以下のとおり(VS2013のF# interactiveで確認したのでちょっと正確な言い方ではないかも)。

Value ("Hi!") {CustomAttributes = [];
               Raw = ...;
               Type = System.String;}

F# 4.0からは次のようになります(VS2015のF# interactiveで確認したのでちょっと正確な言い方ではないかも)。

ValueWithName ("Hi!", a) {CustomAttributes = [];
                          Raw = ...;
                          Type = System.String;}

Expr.ValueWithNameとなり、束縛名が取れるようになりました。

ReflectedDefinitionとメソッド呼び出しでの引数の暗黙的なauto-quotation

https://github.com/fsharp/FSharpLangDesign/blob/5cec1d3f524240f063b6f9dad2f23ca5a9d7b158/FSharp-4.0/AutoQuotationDesignAndSpec.md

上記ドキュメントを読めばわかるとおり

static member Plot([<ReflectedDefinition>] values:Expr<int>) = ...

と定義してあげると

Chart.Plot(f x + f y)

このようなコードは下記の形に暗黙的に変換されます。

Chart.Plot(<@ f x + f y @>)

ReflectedDefinitionのIncludeValueとExpr.WithValue

先ほどのドキュメントにも書かれているとおり

static member Plot([<ReflectedDefinition(true)>] values:Expr<X>) = ...

IncludeValueをtrueにすることで、quotationに変換する際に

Chart.Plot(Expr.WithValue(f x + f y, <@ f x + f y @>))

Expr.WithValue(obj, Expr)の形に変換されるようになります。

Persimmon.Driedによる利用例

いきなり利用例の話…の前に、ちょっとした問題提起から。

今年に入って実装を進めているライブラリの一つにPersimmon.Driedというものがありますが、下記のブログにも述べられているとおり弱点が存在します。

Persimmon.Dried で性質をチェックする — a wandering wolf

今回の話に関連する部分を以下に引用します。

1つは apply した先でテストに失敗した時に、どの apply で失敗したかが明確ではない点です。大体はどこで失敗したか予想はつきますが、1つの property ブロックに複数の apply を入れていると、失敗結果から自明には分かりません。どの Prop が失敗したか、名前が分かるととても捗りますね。

具体的なコードはFuncyというライブラリのテストがわかりやすいと思います。

https://github.com/Gab-km/Funcy/blob/55b9ff30b6508b9089448ea4e54776450fc35af4/Funcy.Test/ApplicativeLawsCheck.fs#L80

Persimmon.DriedのPropnにはラベルをつける機能があるのですが、今回のように変数束縛するのであれば変数名からいい感じに名前を取得して重複させないようにしたいですね? というわけで先ほど紹介した機能の出番となります。

成果物

コードは下記で公開しています。

github.com

ReflectedDefinition、WithValue, NameWithValueを使って名前を取得する

まず、既存のPropertyBuilderには手を入れたくないので別ライブラリとしてコンピュテーション式のビルダーをラップします。 その後、該当部分のメソッド引数にReflectedDefinitionをつけていきます。

// 定義部分だけてきとーに抜粋
member __.Apply<'T, 'U when 'U :> Prop>(s: PropertiesState<'T>, [<ReflectedDefinition(true)>] expr: Expr<'U>) =
member __.ApplyReturn(s, [<ReflectedDefinition(true)>] expr: Expr<Prop<'T>>) =

使う側はモジュールを一つオープンするだけで、変数名がラベルとして表示されるようになります。

実際に名前を取得する部分ですが

https://github.com/persimmon-projects/Persimmon.Dried.Quotations/blob/afc8893b0674902b95c8a08e5e70293e284b75d0/src/Persimmon.Dried.Quotations/Quotations.fs#L15

アクティブパターンを使ってひたすら地道に名前を取得しています。 また、引数の型をExpr<'T>にしておけば値は'Tなことが確定するので、安心してWithValueの第一引数やPropertyInfoで取得できるobjを'Tにダウンキャストできます。

おわりに

Expr は 4.0 になってさらなる可能性をもたらしてくれました。 これらの機能とコンピュテーション式を組み合わせると無限に悪巧みができそう有効活用ができそうなので、もっと使い倒してみたいところですね。

おわりにその2(追記)

Persimmonを実装しているプロジェクトのGitter日本語部屋があるので興味のある型はぜひ。

gitter.im

Scala.jsに対応したscodec-msgpackをリリースしました

この記事は予約投稿です。

id:xuwei さんが ささっと作業してくださったのでリリースしました。

https://github.com/pocketberserker/scodec-msgpack/tree/v0.4.1

v0.4.0はプロジェクトの設定ミスにより空のjarが降って来るだけなのでスルーしてください…。

なんでscala-jsに対応できたのか

  • shapeless は Scala.js をサポートしている
  • scodec-bits も Scala.js をサポートしている
  • 依存している二つのライブラリが Scala.js をサポートしたので、 scodec-core も v1.8.3 から Scala.js をサポート開始
  • scodec-msgpack は scodec-core のみに依存する、かつそんなに変なことはしていない
  • よってプロジェクト設定とテスト部分のみコストをかければ問題なく対応可能

といった形です。 shapeless が Scala.js をサポートしているのはなんというか、すごいですね。 マクロ的とか楽に対応できるものなのだろうか…?

TypeClassを使うようにした

ライブラリを作っておいてアレですが、私自身がscodec-msgpackを使っているというわけではないのでテキトーでいいかなと思ってメンテナンスをさぼり気味でした。

しかし、下記issueがきたので

Make primitive `Serialize`s implicit · Issue #8 · pocketberserker/scodec-msgpack · GitHub

重い腰をあげてimplicitな形式に変更しました。 変更ついでにshapeless.TypeClassも使うようにしたのでそれなりに自動生成できます。 インスタンス増やさないといけないのは…ぼちぼちやろうと思います。

その他

  • Extended -> Extensionにリネーム(破壊的変更なのでついでにやった的な)
  • FastOptJsでメモリをドカ食いするのでsbtoptsのmemをちゃんと設定しないとテストでstackoverflowします
  • Scala.jsのプロジェクト設定、特にクロスビルド設定をやったことがなかったのでちょっとしたところではまって難しい…
  • 次にメジャーバージョンにあげるあたりで1.0.0にすると思います