読者です 読者をやめる 読者になる 読者になる

テスティングフレームワークとSemantic Versioningでなんか考えた

その他

タイトルが釣りっぽくなっていてすみません。

寝起きにぼーっと考えていたら疑問に思ったけど、チラシの裏がないのでここに投げておきます。

この記事は疑問を書いて投げっぱなしにするので解などはかかれていません

Semantic Versioning

Semantic Versioning 2.0.0

semver警察という用語もあるとかないとか。

Evolve slowly

最後にこの話をきいたのはTestingFrameworkMeetingのid:t-wadaさんの資料だったはず。

http://twada.herokuapp.com/presentations/testing_framework_meeting/testing_framework_meeting.html#8

  • Evolve slowly (テストコードは利用者の投資の結果そのものなので、その投資が早いサイクルで無駄になることはない、という安心を与えなければならない)

そのままですね。

ユーザはコードを変更しなくてもいいけど…みたいな話?

  • ユーザはコードを変更しなくてもコンパイルが通る変更
  • しかし互換は崩れる

こういう修正をする必要があったとき、semverに従えばメジャーバージョンを上げる必要があると思います。

で、開発者側としてはバグ修正なのでユーザに最新のバージョンを使って欲しいが、ユーザからは破壊的変更をバンバン行っているように見えるのでEvolve slowlyには反しているんじゃないか、みたいに思えなくもないというか。

いやまぁ、Change log読もうの一言で済むといえばその通りなのですが、メジャーバージョンがガンガンあがるってまだまだわりと抵抗あるんじゃないかなと思う次第です。 テスティングフレームワークなら余計にそう思ったりするのでは、とか。

一旦保留

ということを寝起きで考えましたが考えすぎなのかもしれないし眠いので寝ます。 これを読んで「考えすぎだよ」って思った方はそう私に伝えてください。

PaketとFAKEを使うようにした理由とか

F#

おはようございます。 たぶんこの時間帯は寝ているので、この記事はきっと予約投稿(どうでもいい)。

ここ数日、重い腰をあげて開発したりメンテしたりしているF#系ライブラリの一部でPaketとFAKEを使うようにしたり、最近の書き方に合わせた。

今回対象にしたのは下記のライブラリ。

https://github.com/persimmon-projects/Persimmon https://github.com/persimmon-projects/Persimmon.Dried https://github.com/pocketberserker/FAKE.GitBook https://github.com/persimmon-projects/Persimmon.Dried.Quotations https://github.com/pocketberserker/FAKE.GitBook

基本はProjectScaffoldを参考に、各プロジェクトごとに細かい変更をしている。 ProjectScaffoldはパブリックドメインなので遠慮なく参考にしましょう。

細かい嵌りどころ

  • そもそもディレクトリ構成が全然違うものは合わせるのに時間がかかる
  • frameworkAssemblyFSharp.Coreが設定されているライブラリを参照すると、思いもよらないFSharp.Coreの重複参照を招く
    • しかもエラー場所がわかりづらい…
    • Paketは今のところ回避手段がない
    • paket installpaket updateで毎回この問題にぶつかるため、温かみのある手作業をする必要がある
  • nuspecでできることがすべてpaket.templateでできるわけではない
    • バージョン参照とか現状無理
    • とはいえ、nuspecよりもpaket.templateのほうが楽な部分もあるのでどっちもどっち

なぜPaketを使うようにしたか

そこそこ前からF#界隈だとデファクトスタンダードだったこいつを、なんで去年あたりからようやく使い始めたのかというと

  • いきなりVisual Studio上でビルドしてもちゃんと依存パッケージをダウンロードしてくれるようになった
    • 正直これが大きい
    • 以前はコマンド叩いてからVS上でビルド…という工程がつらくて使わなかったというのが原因の7割
  • Paket.VisualStudioができた
    • とはいえGUIを一回も使ったことがない…
  • Visual Studio 2015からnugetからのrestoreを設定してもnuget.exeが入ってこなくなった
    • 移行理由の3割
    • TravisCIとかを考えるとプロジェクト同梱のほうが楽だなと感じている
      • これは人それぞれだと思う

そういえば最近、groupによって依存パッケージを細かく分離できるようになったようだ。 おかげでProjectScaffold内の各種pathも変更されていて、なし崩し的に対応する必要がでたがそこはまた別の話。

とはいえ、NuGetで困らないレベルのライブラリ群は引き続きNuGetでやるつもりである。

なぜFAKEを使うようにしたか

DSLが不評だったり若干もっさりするなど、色々言われていたビルドツールFAKEさん。 私は消耗したくないのでPowerShellbashで書けばいいや(それはそれで消耗するのでは、とか突っ込みはなしで)とかずっと思っていましたが、まぁ色々とあるのですよ…。

  • 別言語のビルドツールを使っていたら、抵抗するのがむなしくなった
    • npm(+gulp)、sbt、gradle、rebar、mix、etc…
    • あれ、どれも大差ないじゃんという気持ちに(もちろん人によって異論はあるだろう)
    • 各言語のデファクトスタンダードを使っておけば数年は死なないだろうという結論に至った
  • Paketによって敷居が若干下がった?
    • NuGet時代はどこにpackage.configを置くか悩んだ
    • 悩んだ結果、使わなかった
  • Gitへのコミットやその他の操作をPowerShellbashでひたすら頑張ることの限界
    • 消耗し始めた
    • PowerShellbashに強いマンではないので…

特に積極的な理由はないという…すみません。

まとめ

デファクトスタンダードには巻かれよう。

そのうち強い人たちがもっといいものを作ってくれる。

そういう未来を信じるんだ!

最近使っている F# のライブラリやツール

F#

下記のF#版です。

最近使っているScalaのライブラリ - pocketberserkerの爆走

ここ1年くらいのものを対象にしています。

といってもそんなに数はない…。

ライブラリ

自分が開発に関わっているものは除外しています。

FSharp.Data

https://github.com/fsharp/FSharp.Data

まぁ、FSharp.Data.JsonTypeProviderばかり使っているわけですが…。

FsRandom

https://github.com/kos59125/FsRandom

Persimmon.DriedがFsRandomに依存している関係上、一番お世話になっているかもしれない。

FsCheck

https://github.com/fscheck/FsCheck

新しく作るときはPersimmonシリーズを使っているのですが、既存のライブラリや他の人が作っているライブラリでは使っているので。

FsUnit

https://github.com/fsprojects/FsUnit

FsCheckとだいたい同じモチベーションで使っている。

FsPickler

https://github.com/nessos/FsPickler

関数のシリアライズのお供に。

FsYaml

https://github.com/bleis-tift/FsYaml

他のライブラリを探すのが面倒なのでなんとなく使っている。

FSharp.TypeProviders.StarterPack

https://github.com/fsprojects/FSharp.TypeProviders.StarterPack

TypeProviderのお供に。

FSharp.Formatting

https://github.com/tpetricek/FSharp.Formatting

ドキュメントでひたすらお世話になっている。

FSharp.Quotations.Evaluator

https://github.com/fsprojects/FSharp.Quotations.Evaluator

使っているというかforkしているというか。。。

ツール

わりとあった。

Paket

https://github.com/fsprojects/Paket

VS2015あたりからnugetの実行ファイルがくっついてこないのでこっちに切り替えた。 FAKEもセットで使うことが多い。

VS拡張の登場によって以前ほど抵抗がなくなった。

https://github.com/fsprojects/Paket.VisualStudio

FAKE

https://github.com/fsharp/FAKE

nugetにpublishする必要があるライブラリでは使っている。 が、あまり好きではない(AutoOpenするスタイルが……)。

FsReveal

https://github.com/fsprojects/FsReveal

F# のコードをのせる必要があるスライドを作成する時にお試しで使ってみている。

VisualFSharpPowerTools

https://github.com/fsprojects/VisualFSharpPowerTools

略してVFPT。Visual Studioで F# 書くならほぼ必須。だが重い。

使ってないけど有名そうなもの

一応紹介。

FsControl, FSharpPlus

https://github.com/gmpl/FsControl

https://github.com/gmpl/FSharpPlus

型クラス系のアレ。

FParsec

https://bitbucket.org/fparsec/main

実はちゃんと使ったことがない(業務でもたまたま遭遇しなかった)。

ProjectScaffold

https://github.com/fsprojects/ProjectScaffold

スクリプトは参考にさせてもらいつつ、しかしこれを使ってプロジェクトを作成したことはない……。

FSharpLint

https://github.com/fsprojects/FSharpLint

VFPTでの設定は切っているのでお世話になっていない……。

FSharp.Compiler.Service

https://github.com/fsharp/FSharp.Compiler.Service

間接的にお世話になっているが、実際に導入したことはなかったりする。 なかなか機会に恵まれない……。

終わりに一言

多分他の人とはラインナップが全然違うだろうなぁ……。

FAKEとgitbookとAppVeyorを組み合わせて、自動でビルドして生成したhtmlをgh-pagesブランチにcommitとpush

F#

あけましておめでとうございます。 年末年始の息抜きでやってたものをまとめておきます。

gitbookとtutとtravis-ciを組み合わせて、自動でビルドして生成したhtmlをgh-pagesブランチにcommitとpush - scalaとか・・・

これを F# でやろうという話です。

FAKEとかgitbookとかAppVeyorの説明はしません。

FAKE.GitBookに関しては試作段階の話を書きました。 なおFAKE.GitBookはちょっと手直しした版をnugetに公開しています。 ただてきとーに作っているので今後もAPIが変わりそうです……。

GitBookを出力するためのFAKE拡張の試作品を作った #FsAdvent - pocketberserkerの爆走

というわけで、成果物が下記になります。

  • https://github.com/pocketberserker/FAKE.GitBook.Sample
  • http://pocketberserker.github.io/FAKE.GitBook.Sample/

  • AppVeyorでのgit push権限周りに関してはこのページの方法を使いました。 本当はsshのやつにしたほうが良いのでしょうが、体力切れのため後日対応で……。

  • 肝心のpushに関してはFAKEに丸投げしました。最初powershellで書いてたけどだんだん面倒になった……
  • chocolateyでcalibreをインストールしていますが、そのままではパスが通ってないのでpdf生成時にコマンドがないと言って怒られます。なのでパスを追加で設定します。
  • 元ネタ記事のほうではTextLintにも対応されていますが、こちらではまだ入れていません。そのうち入れます。
  • 記事のタイトルで"htmlをgh-pagesブランチにcommitとpush"とか言ってますが、それ以外にもpdfとepubを生成してartifactsとして保存しています。

気が向いたらドキュメントなり資料なりを書いていきたい……

2015年簡易振り返り

その他

書いておかないと忘れるけどもう時間がないので簡易版。

生活

  • F# MVPから.NET MVPになった
    • MVPらしい活動をしていたかどうかは微妙なところだが、なんかやってはいた気がする
  • 転職した
    • 転職の際にScalaMatsuriの情報を使わせてもらったお礼にと思ってインタビューを受けたが、インタビューを受けるのはこれが初だったのでわりと緊張した
    • やはり東京にいると便利だなと思うことが多い
    • しかし地元九州からさらに遠ざかってしまった…移動が面倒だったので今年は帰省していない
  • 生活時間が順調に狂った
    • ただし、転職以前に感じていた寝起きのつらさ的なストレスが消えたのでこれはこれで良かったのかもしれない
  • 年末になってようやく引っ越し貧乏から脱出しつつある
  • ゲームはコンスタントに買って消化していた気がする
    • 去年からの積みゲーがそのままになっている問題…
  • なんだかんだひと月一記事以上ブログ書いてたらしい

言語

  • F#: ほぼプライベートオンリーだけどなぜかわりと触ってた
  • Scala: ほぼプライベートオンリーだけど(ry
  • TypeScript: 諸事情で手を出した
  • Elixir: 諸事情で手を出した
  • Erlang: ちょっとだけ書いたけど思った以上に書かなかった
  • SML#: なぜか一時期書いてた
  • C++: 諸事情で書いた
  • Rust: nomを触るためにちょっと学んだ
  • Haskell: 読む力は上がったが一切書いた記憶がない

Rustを本腰入れてやりたい気もしつつ、Idrisに挑戦したい気もしつつ、Coqから目を背けないほうがいいのか…色々考えても結局なるようにしかならないので考えるのをやめよう。 来年のことは来年の私が頑張ってくれるはずだ。

ライブラリは産廃なものと形になったもので半々といったところ。 まぁ、使うことを目的としていないのでこんなものではないだろうか。

イベントとか

会社のセミナールームが使えることに味を占めて色々開催したりお手伝いしていた気がする。

  • Lens & Prism
  • F#談話室(これは一回会場手配しただけだけど
  • 関数型Scalaの集い
  • 関数プログラミング交流会
  • Testing Framework Meeting
  • 関数型ストリーム処理勉強会(これは相談を受けて開催したやつ)
  • Oleg勉強会

個人的には、知らないことが何か知れたという点で非常に満足度の高いものだった。

あと、なんだかんだで発表していたようだ。

ペースは落ちるかもしれないが、何回かは発表したいところだ。

.NET系の勉強会に顔を出したいと思いつつなかなか足を運べていないのでなんとかしたい。

締め

気の向くままに。

お前もnullにしてやろうか! #FsAdvent

F#

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

ガス欠なので役に立たないネタでお茶を濁します。

Noneはnullと解釈できる

F#erの皆様はたいていprintf "%A" Noneを実行して<null>と表示されることに落胆したことがあるのではないでしょうか。 私は落胆しました。

同じようなことをやってみる

[<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
type A<'T> = B | C of 'T
with
  [<CompilationRepresentation(CompilationRepresentationFlags.Instance)>]
  member this.Value = match this with | C a -> a | B -> failwith "oops!

CompilationRepresentationFlags.UseNullAsTrueValueを指定することで、引数をとらない識別子をnullとして表現可能になります。 こいつを付けた状態でメンバーにCompilationRepresentationFlags.Instanceを付けなかったら、そのメンバーは静的にコンパイルされます。

使いどころは?

  1. .NETが絡む
  2. その判別共用体の中で引数をとらない識別子が一つのみ
  3. nullにしてもよいと思った場合

これがそろったら使うか…? くらいの認識です。 ぶっちゃけ使うことはないだろうと思っています。

気を付けるべきとき

自分は使わないとはいえ、どのライブラリも使わないということは言えないので、対処してあげる必要があったりします。

ぱっと思いつく罠にはまるパターンはPretty Printerですね。

あとは box したときにやらかしそうとかですかね。

結論

使うな。だが注意せよ。

追記

こうしてnullに表現可能になった識別子は、コンパイルしたらUnchecked.defaultofでnullではなく代わりにunion caseのほうが使われるみたいですね。 F# Interactiveではnullが返ってきたので、コンパイラが色々やっている模様。

GitBookを出力するためのFAKE拡張の試作品を作った #FsAdvent

F#

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

最近はやりのあの子

最近GitBookが流行っぽいですね。

GitbookIO/gitbook · GitHub

そんでもって、Scala界隈では下記リポジトリのようにtut + GitBookでいい感じにコンパイルチェックもできるような感じのようです。

xuwei-k/gitbook-sample · GitHub

これ、F# でもやりたいですね?

そして F# 界隈には FAKE と FSharp.Formatting がありますね?

よろしい、ならば連携だ。

FAKE.GitBook

pocketberserker/FAKE.GitBook · GitHub

FSharp.FormattingにはMarkdown出力がない*1ので、GitBook用のMarkdownを出力するようにします……と言えればかっこよかったのですが、まだ試作品なのでそこまでちゃんと動きません。

あと、現時点で既にわりと力尽きかけているので、本格的に使い方がコントリビューションお願いします…。

使い方

GitBookとの連携が前提になっているので、package.jsonbook.jsonが必要です。

あとは FAKE と FAKE.GitBook をロードして以下のようにスクリプトを書きます。

open Fake

Target "GenerateBook" (fun _ ->
  GitBook id (fun p -> { p with SrcDir = currentDirectory @@ "doc" }) Html
)

RunTargetOrDefault "GenerateBook"

pdfやepubを出力したいなら、Htmlの部分をPdfやEPubにすればいいです。

終わりに

以上、年末恒例の進捗帳尻合わせ回でした。

*1:Markdown、方言すぎだからあっても困る