CC BY-SA 4.0
- なかやん・ゆーき / ぺんぎん / もみあげ
- @pocketberserker / id:pocketberserker
- Microsoft MVP for
F#(2013/04/01~ 2017/03/31)- Visual Studio and Development Technologiesって長すぎぃ
- ドワンゴ所属(.NETな仕事をしているわけではない)
- .NET系のイベントで喋るのは2回目
- 名古屋で行われた.NET基礎勉強会以来
.NET Fringe Japanの概要に書かれているのは" .NETに関する深く詳細な話題を主に取り上げます"とある。
が、朝から F# の濃い話を聞きたい人なんているのか?
……と思ったので、雑多に F# を紹介することに。 そういうわけで、DeepではないDive。
https://github.com/Microsoft/visualfsharp
- Microsoft ResearchのDon Symeさんがdesign
- マルチパラダイム
- 関数プログラミング寄り
- .NET Framework向け
- コアライブラリは.NET Core対応中(今のところα版)
- F# Software Foundation
- 最新バージョンは 4.0
- vNextは4.1というアナウンスあり
(ここで過去のイベントで紹介したものをざっと眺める)
いくつか追加するなら
printfn "%A"
でそこそこ中身が表示できる- officialでDocker imageが公開されている https://hub.docker.com/_/fsharp/
ことだろうか。
printf
は人によって好みがわかれるだろう。
String Interpolation(まだRFC段階)
が入れば印象が変わる可能性もある?
ついでに、あまりふれいていなかった部分について触れておく。
正直、慣れの問題である。 書いていればそのうち慣れる。
とはいえ、オフサイドルールが好みにそぐわない人もいると思われる。 軽量構文をoffにすることもできるが、軽量構文が推奨されているので悩ましいところ。
個人的には「郷にいては郷に従え」と考えているが。
F#では前方で定義した型や関数しか使えない。 ソースファイルも順番通り並べないとコンパイルエラーになる。
依存順序を明確にしやすいので重宝することが多いが、不便なときもある。
目下一番の問題は.NET Coreのproject.jsonにファイルを追加するとき。 手作業でやらなければならない前時代さよ…。
C#のメソッドチェーンスタイルに比べるとかったるいかもしれない。
RFCにはあるのでそのうち入るはず。
値が存在しないかもしれないことを型で表し処理を強制させるか、利用者側で必要な時に伝搬、チェックさせるかの違い。
自信があればNull-conditional operatorsで良いかもしれない。 私はやらかす自信しかないのでOptionを使う。
あと、当たり前だがなんでもかんでもOptionで返すわけではない。 必要ならちゃんと型を定義する。
type Result<'Success, 'Error> =
| Succcess of 'Success
| Error of 'Error
type Reason =
| NotFound of (resource: string)
| BadRequest of (message: string)
...
let badRequest message = BadRequest message
ちなみに RFCでResult型が提案されている。
F#にはAsync型というものが定義されている。 便利ではあるのだが、これはこれで嵌りどころが多い。
https://github.com/kekyo/FSharp.Control.FusionTasks
こういうライブラリが生み出されるくらいTaskとの連携は頭を使う?。 (Async周りはkekyoさんを捕まえたほうが詳しい話をきけると思われる)
「F#って何ができるの?」
汎用プログラミング言語だし.NET Frameworkの資産が使えるので、 C# でできることはだいたいできるはず (しかしUWPをF#のみで開発はできない…)。
仕事で使った、という話は私には荷が重いので割愛。
ここでは私が関わったものを例にあげてみる。
https://github.com/fsdn-projects/FSDN
http://fsdn.azurewebsites.net/
シグネチャや名前でF#のAPIを検索できるサービス。 (個人的には)F#のAPIよりも.NET Frameworkのメソッド検索で重宝している。
次のリリースで検索結果にMSDNへのリンクがつくようになる。
ロゴはお気に入り。
主にその時使いたかったもので構成されている。
- Suave
- F#製の軽量ノンブロッキングWeb Server
- https://suave.io/
- FAKE
- ビルドツール。F#スクリプトを用いる。
- http://fsharp.github.io/FAKE/
- TypeScript
- フロントは別言語
- なぜTypeScriptかは後述
- Azure App Service Web Apps
- とある会社に出資、運用していただいている
- Docker
- 非Windows環境でも動くことを確認するため
デプロイにはKuduSyncを使用(このあたり)。 このあたりは言語差関係なし。
"F# to JavaScript Compiler"であるFable。
https://github.com/fable-compiler/Fable
使わなかった理由はそこまでViewにコストをかけたくなかったから。 絶賛開発中のFableを使うと無限にリソースを持っていかれる予感がした(私はよく脱線する)。
クライアントとサーバで言語を統一でき、型検査の恩恵にあやかれるメリットはあるが、この時はデメリットのほうが多かった。 もう少し大規模になるなら導入したかもしれない。
私はこの部分の開発にノータッチだが、わりとF#さが溢れているので紹介する。
- 検索クエリ部分
- 入力されたクエリを解析する必要があるため、解析器を作る必要がある
- 正規表現だけで実装するのは無理ゲー
- Parser Combinatorを使えば比較的容易にParserが作れる
- 手のコードはF#だとわりと書きやすい
- FSharp.Compiler.Service
- Roslyn的なやつ
- この手の言語サービスは
- シリアライザ
- FsPicklerというF#向けシリアライザ
- 関数もシリアライズできる…?
Suaveの機能を使っている、以上。
JSONライブラリはFSharp.Data、Json.NETの利用も考えたが、最終的にDataContractJsonSerializerに落ち着いた。 他言語で開発されたライブラリ、F#向けライブラリ、.NET Frameworkと選択肢が多いのが良い。
F#でのユニットでは、NUnitやxUnit.NETをラップしたFsUnitを使う人が多い。 あとはFsCheckと呼ばれるランダムテスト。
が、FSDNのテストにはPersimmonという自作のF#用テスティングフレームワークを使っている。 属性ベースのparameterized testで型ミスを何度もやらかした結果、属性ベースではない型安全なテスティングフレームワークがほしくなったため。 なければ作ろう。
とはいえ、Persimmonは未だ課題も多い。 Visual Studio Test Explorer拡張が未完成(メイン開発者が多忙)なためVSのデバッグ機能が使えない。 ただこれの開発はFSharp.CoreとTest Explorerの相性が悪いその他さまざまな闇を抱えているため、実装できる人が限られている……。
残念ながらここ2, 3年で和書が出版されたという話は聞かない。 基本的な部分はF# 2.0の知識でも十分なので、技評の"実践F#"やオライリーの"プログラミングF#"で学ぶのも手。
洋書は色々あるのでぐぐるべし。
ぎたぱそさんの記事で雰囲気がつかめるのではないだろうか。
http://qiita.com/u_1roh/items/eb90672fc40fc7f2ea86 は仕事で導入されたという話を含めて読み応えがある。
- C# 7で入りそうな機能が既に入っている
- 2016年10月現在であれば、F#で勘所を抑えてC#で存分に生かすという手段を取るのも手か
- F#で普通に何か作れるという一例の紹介
- 今回はF#製ライブラリが多かったが、C#製ライブラリも結構使う
- 入門方法について
- 問題は感じているが対策が…
- 秘密結社は存在しません(たぶん)