SlideShare una empresa de Scribd logo
1 de 39
解説?
FSharp.Quotations.Compi
ler
bleis-tift
自己紹介
id:bleis-tift / @bleis
株式会社オンザロード アーキテクト
F# / Git / 関数プログラミング / SQL
◦ wantedly調べ
今日話すこと
F#の式木の実行器事情
まともな実行器のつくりかた
今後の展望
F#式木実行器事情
F#の式木実行器の必要性
C#では式木を実行するためのメソッドが用意されて
いる
public static void Main()
{
SomeMethod(x => x * 2);
}
static void SomeMethod(Expression<Func<int, int>> expr)
{
var f = expr.Compile(); // !!!
Console.WriteLine(f(21)); // !!!
}
F#には標準では用意されていない・・・
外部ライブラリの式木実行器たち
(FSharp.Quotations.Compiler以
外)
F# Power Pack - Quotations Compiler
FSharp.Quotations.Evaluator
QuotationCompiler
Unquote
他にもあるかも?
F# PowerPack
F#チームが提供していた追加ライブラリ(とツール)
群
この中に「Quotations Compiler」というライブラ
リがあった
let expr = <@ fun x -> x * 2 @>
let f = expr.Compile()() // Compile()でunit -> ‘aが得られる
printfn “%d” (f 21)
F#の式木を.NETの式木に変換するスタイルF#の式木
.NETの式
木
.NETの機
能で実行
F# PowerPackの問題点
非推奨
.NETの式木への変換が非末尾再帰
◦ 変換対象が大きいとスタックオーバーフローする
バグが多い
◦ int “42” を実行しようとしただけで落ちる
◦ 他にもいろいろ
変換も実行も遅い
◦ 変換が愚直すぎて変換後の.NETの式木がアレ
FSharp.Quotations.Evaluator
F# PowerPack Quotations Compilerの後継
F# PowerPack Quotations Compilerとだいたい同
じ
◦ パフォーマンスはある程度改善されている
CompileじゃなくてEvaluateで直接実行
let expr = <@ fun x -> x * 2 @>
let f = expr.Evaluate()
printfn “%d” (f 42)
FSharp.Quotations.Evaluatorの問
題点
.NETの式木への変換が非末尾再帰
◦ 変換対象が大きいとスタックオーバーフローする
バグが多い
◦ int “42” を実行しようとしただけで落ちた(修正済み by bleis)
◦ 他にもいろいろ
QuotationCompiler
F#の式木をFSharp.Compiler.Serviceの提供する
ASTに変換して実行するスタイル
let expr = <@ fun x -> x * 2 @>
let f = QuotationCompiler.ToFunc expr
printfn “%d” (f 21)
変換後のコード実行速度は爆速
F#の式木 FCSのAST
FCSで
コンパイル
実行
QuotationCompilerの問題点
動的アセンブリに非対応
コンパイルに時間がかかる
◦ FSharp.Compiler.Serviceが重いのでこれはどうしようもない感
ASTへの変換が非末尾再帰
Unquote
F#の式木を直接実行していくスタイル
let expr = <@ fun x -> x * 2 @>
let f = Unquote.eval expr
printfn “%d” (f 21)
本来の用途はPowerAssert的なもので、実行器はオマ
ケ?
F#の式木
式木を走査
しながら実行
Unquoteの問題点
実行速度がとても遅い・・・
実行が非末尾再帰
当時求めていた実行器
スタックオーバーフローを起こさない
変換が遅くない
実行も目を見張るほど遅くない
十分テストされている
これらを満たす実行器は存在しない・・・
ないなら作ろう実行器
目指すところ
◦ スタックオーバーフローを起こさない
◦ 変換が十分に速い
◦ 実行が十分に速い
◦ 十分テストされている
命名: FSharp.Quotations.Compiler(略称FQC)
F#の式木 IL
ロードし
て実行
まともな実行器のつくりかた
FSharp.Quotations.Compiler作成過程
用意するもの
F#の式木に関する理解
CPS変換に頼らずに末尾再帰を書き下す能力
もしくは、再帰的なものをループで実現する能力
ILに関する理解
F#の式木に関する理解
式木ってそもそも何?
どんなコードがどんな式木になるのかわかってれば
OK
わからなければ
◦ Microsoft.FSharp.Quotations.Patternsモジュールを眺める
◦ 書いてあるアクティブパターンにマッチするコードクォートを書いて
みる
◦ 全部できればOKでしょう
スプライスも使えれば完璧
CPS変換に頼らずに
末尾再帰を書き下す能力
F#はCPS変換してもスタックオーバーフローは避けら
れない
◦ 再帰関数のスタックオーバーフローを倒す話 その2 参照
◦ はっきりと原因はわかっていないが、実際起きるから仕方ない
それはそれとしてCPS変換を理解する過程は楽しかった
のでみなさんも是非どうぞ
◦ 再帰関数のスタックオーバーフローを倒す話 その1 参照
人間やめたくないのでこの道はあきらめた
再帰的なものをループで実現する能
力
再帰はあきらめて、再帰的なものをループでやればい
い
◦ 何をどこまで変換し、何が残っているのかを管理しなければならない
ので、スタックが必要になる
◦ クイックソートをループで書ければOK
◦ 再帰関数のスタックオーバーフローを倒す話 その3 参照
人間やめなくてすんだ
ILに関する理解
IL ≒ .NET向けバイトコード
.NETの式木に変換しても良かったけど、面白みに欠
ける
◦ FSharp.Quotations.Evaluatorとかぶるし・・・
なぜかILに変換する実行器は存在しない
メタプログラミング.NET の5章が理解できれば基本
はOK
ここまでそろえれば、あとはつくるだけ!
つくりかた
F#コード片をコンパイルする
生成されたILを読む
◦ Ildasm.exeやILSpyなどお好みで
F#の式木から上記ILが生成されるようなコードを書
く
◦ System.Reflection.Emit.ILGeneratorでゴリゴリと
上記手順をひたすら繰り返す
FQC開発Tips
開発はDevelopment構成で行う
◦ コンパイル&テスト時間とデバッグのしやすさのバランスが取れた構成
◦ コンパイルした式木に対応する簡易なILファイルが生成される
デバッグはDebug構成で行う
◦ デバッグシンボル付きなので生成したILにステップインして実行でき
る
◦ 全部のテストを実行すると遅いので、一つのテストのデバッグ実行に
使う
リリースにはRelease構成を使う
◦ 余分なファイルを生成しない
完成!
・・・してません
FSharp.Quotations.Compilerには未実装機能がた
くさん!
◦ forやwhileが未実装
◦ let recが未実装
◦ ループするすべがない・・・!
使いたかった案件ではループが不要だったの
でぇ・・・
今後の展望
FSharp.Quotations.Compilerのこれから
やること
完成させる
◦ せめてループが実行できないとまともな実行器とは言えない
◦ そもそもベンチマーク取れない・・・
テストの追加
◦ まだまだ全然足りてません・・・
リファクタリング
◦ xxx_Sとか意識しなくて済むようにAIL(abstract IL)を定義したい
◦ 他にもいろいろ
やりたいこと
高速化
◦ 正しく動作することを念頭に開発したので、高速化の余地がある
◦ 組み込み型の比較にoperator ==を呼び出していたりする
式木最適化ライブラリの提供
◦ FSharp.Quotations.Evaluatorなどでは実行器にセットになっている
◦ 実行器は式木の形を変えるようなことをしない方がいいという考え
◦ 外部の独立したライブラリとして提供したい
ドキュメントの充実
やれるといいこと
言語外DSLを作るの楽しい
フロントエンドはFParsec等ある
バックエンド、ILはサポートが手厚くて至れり尽くせ
りと今回わかった
VS拡張に関する知識もそれなりにある
VSのいろんな機能に対応した言語外DSLの開発とか?
私と一緒に実行器をつくりません
か?
おまけ
いままで遭遇したバグとかその他諸々
tryが式であることの罠
C#ではtryは文だが、F#では式
let f x = x + 10
f (try g () with e -> 0)
これを単純にemitしてしまうと、leave命令によって
評価スタックが空にされてしまう!
◦ fへの参照が評価スタックに残っているのに・・・
tryを無名関数でラップすることで回避
let f x = x + 10
f ((fun () -> try g () with e -> 0)())
tryの最適化案
try-withの結果型がunitの場合や、try-finallyの場合
は無名関数によるラップは必要ない?
◦ もしそうであれば、その場合はラップせずに直接emitしてしまえばい
い
tryが関数の最後のブロックの場合、無名関数による
ラップは必要ない
◦ そのまま実行すればいい
◦ 最後のブロックがif-then-elseの場合、thenやelseにtryがあっても成
り立つ
◦ 「最後のブロック」は「末尾位置」と同じ?
mutableとtryの組み合わせ
tryは無名関数でラップされる
無名関数はクラスで実現
tryの中でmutableな変数を書き換えると・・・
◦ 現在の実装では、mutableな変数を呼び出し元のコンテキストで再設
定していない
◦ 呼び出し元の値が書き換わらない
特殊な関数たち
reraise関数
◦ 普通に呼び出すとアウト
(..), (.. ..)演算子
◦ 式木として得られる汎用のものを呼び出すと、微妙に挙動が変わる
NoDynamicInvocation属性がついた関数
◦ それ自身は実行できる(標準ライブラリに定義されているものに限る)
◦ これを含むinline関数は実行できない
ANDパターン
アクティブパターンは結果をactivePatternResultと
いう変数名で受け取る式木に変換される
変数の環境を単なる名前で管理していると、ANDパ
ターンを使って一つのケース内に複数のアクティブパ
ターンを書いた場合にバグる
名前で管理せずに、素直にVarオブジェクトを使えば
いい
コードクォートとExprクラスの違い
コードクォートでできることはExprクラスでできる
<@ if true then 10 else 20 @>
Expr.IfThenElse(Expr.Value(true), Expr.Value(10),
Expr.Value(20))
その逆は成り立たない
Expr.Value(DateTime.Now)
<@ DateTime.Now @> // => Expr.PropertyGet(DateTime.Nowの
PropertyInfo)
式木が期待されるところにはできる限りコードクォー
ト
で得たものを使ったほうが無難
式木から読み取り専用フィールドに
アクセスできない
「Quotations cannot contain inline assembly
code or pattern matching on arrays」
配列のパターンマッチでも、アセンブリコードのイン
ライン埋め込みでもないんですけど・・・
https://github.com/Microsoft/visualfsharp/blob/fsharp4/src/fsharp/creflect.fs
#L447-L449 static fieldとinstance fieldで扱いが違
う・・・!
式木が巨大になりすぎる
ドンちゃん「F#コンパイラはgotoを使ってパターン
マッチでの分岐の重複を除去するが、コードクォート
では(gotoに対応する機能がないので)除去できない」
アクティブパターンを使いまくると式木が簡単に巨大
化するので、そうならないように注意してコードを書
くしかない
.NETの式木にはExpression.Gotoがあるけど、
F#の式にそもそもgotoがないからExprにはGotoは
(たぶん)入らない

Más contenido relacionado

La actualidad más candente

プログラミング言語 Ruby 2章 Rubyプログラムの構造と実行
プログラミング言語 Ruby 2章 Rubyプログラムの構造と実行プログラミング言語 Ruby 2章 Rubyプログラムの構造と実行
プログラミング言語 Ruby 2章 Rubyプログラムの構造と実行
monglee
 
Rのコードをキレイに見せたい
Rのコードをキレイに見せたいRのコードをキレイに見せたい
Rのコードをキレイに見せたい
mangantempy
 
.NET micro FrameWork for TOPPERS (.NET基礎)@基礎勉強会
.NET micro  FrameWork for TOPPERS  (.NET基礎)@基礎勉強会.NET micro  FrameWork for TOPPERS  (.NET基礎)@基礎勉強会
.NET micro FrameWork for TOPPERS (.NET基礎)@基礎勉強会
Kiyoshi Ogawa
 
スペル修正プログラムの作り方 #pronama
スペル修正プログラムの作り方 #pronamaスペル修正プログラムの作り方 #pronama
スペル修正プログラムの作り方 #pronama
Hiroyoshi Komatsu
 
C++でぼくが忘れがちなこと
C++でぼくが忘れがちなことC++でぼくが忘れがちなこと
C++でぼくが忘れがちなこと
Toshihiko Ando
 
C言語の宣言読み方講座
C言語の宣言読み方講座C言語の宣言読み方講座
C言語の宣言読み方講座
tetra_cat
 

La actualidad más candente (20)

Excel出力のCSV取込みから学ぶ4つのCPANモジュール
Excel出力のCSV取込みから学ぶ4つのCPANモジュールExcel出力のCSV取込みから学ぶ4つのCPANモジュール
Excel出力のCSV取込みから学ぶ4つのCPANモジュール
 
Nom de fonction français
Nom de fonction françaisNom de fonction français
Nom de fonction français
 
C#や.NET Frameworkがやっていること
C#や.NET FrameworkがやっていることC#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること
 
プログラミング言語 Ruby 2章 Rubyプログラムの構造と実行
プログラミング言語 Ruby 2章 Rubyプログラムの構造と実行プログラミング言語 Ruby 2章 Rubyプログラムの構造と実行
プログラミング言語 Ruby 2章 Rubyプログラムの構造と実行
 
型の話
型の話型の話
型の話
 
Rのコードをキレイに見せたい
Rのコードをキレイに見せたいRのコードをキレイに見せたい
Rのコードをキレイに見せたい
 
コピーの話
コピーの話コピーの話
コピーの話
 
C# 9.0 / .NET 5.0
C# 9.0 / .NET 5.0C# 9.0 / .NET 5.0
C# 9.0 / .NET 5.0
 
201903 のの会@関数Talk 10th
201903 のの会@関数Talk 10th201903 のの会@関数Talk 10th
201903 のの会@関数Talk 10th
 
○○型言語と呼ばれるために備えるべき最低限の条件についての検討
○○型言語と呼ばれるために備えるべき最低限の条件についての検討○○型言語と呼ばれるために備えるべき最低限の条件についての検討
○○型言語と呼ばれるために備えるべき最低限の条件についての検討
 
Kanrk05 .Netでお仕事しているプログラマがスクリプト言語として使うRuby
Kanrk05 .Netでお仕事しているプログラマがスクリプト言語として使うRubyKanrk05 .Netでお仕事しているプログラマがスクリプト言語として使うRuby
Kanrk05 .Netでお仕事しているプログラマがスクリプト言語として使うRuby
 
C#言語機能の作り方
C#言語機能の作り方C#言語機能の作り方
C#言語機能の作り方
 
.NET micro FrameWork for TOPPERS (.NET基礎)@基礎勉強会
.NET micro  FrameWork for TOPPERS  (.NET基礎)@基礎勉強会.NET micro  FrameWork for TOPPERS  (.NET基礎)@基礎勉強会
.NET micro FrameWork for TOPPERS (.NET基礎)@基礎勉強会
 
正規表現
正規表現正規表現
正規表現
 
スペル修正プログラムの作り方 #pronama
スペル修正プログラムの作り方 #pronamaスペル修正プログラムの作り方 #pronama
スペル修正プログラムの作り方 #pronama
 
C++でぼくが忘れがちなこと
C++でぼくが忘れがちなことC++でぼくが忘れがちなこと
C++でぼくが忘れがちなこと
 
C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話
 
C++ tips2 インクリメント編
C++ tips2 インクリメント編C++ tips2 インクリメント編
C++ tips2 インクリメント編
 
「もうなにもこわくない」関数型言語 〜ふつうのプログラマが関数型言語を知るべき理由・reload〜
「もうなにもこわくない」関数型言語 〜ふつうのプログラマが関数型言語を知るべき理由・reload〜「もうなにもこわくない」関数型言語 〜ふつうのプログラマが関数型言語を知るべき理由・reload〜
「もうなにもこわくない」関数型言語 〜ふつうのプログラマが関数型言語を知るべき理由・reload〜
 
C言語の宣言読み方講座
C言語の宣言読み方講座C言語の宣言読み方講座
C言語の宣言読み方講座
 

Destacado

仕事で使うF#
仕事で使うF#仕事で使うF#
仕事で使うF#
bleis tift
 
ぼくのかんがえたさいきょうのLL
ぼくのかんがえたさいきょうのLLぼくのかんがえたさいきょうのLL
ぼくのかんがえたさいきょうのLL
bleis tift
 
輪るビングドラム.NET
輪るビングドラム.NET輪るビングドラム.NET
輪るビングドラム.NET
bleis tift
 

Destacado (20)

仕事で使うF#
仕事で使うF#仕事で使うF#
仕事で使うF#
 
yieldとreturnの話
yieldとreturnの話yieldとreturnの話
yieldとreturnの話
 
F#事例発表
F#事例発表F#事例発表
F#事例発表
 
モナドハンズオン前座
モナドハンズオン前座モナドハンズオン前座
モナドハンズオン前座
 
Better C#の脱却を目指して
Better C#の脱却を目指してBetter C#の脱却を目指して
Better C#の脱却を目指して
 
効果の低いテストの話
効果の低いテストの話効果の低いテストの話
効果の低いテストの話
 
No more Legacy documents
No more Legacy documentsNo more Legacy documents
No more Legacy documents
 
JSX / Haxe / TypeScript
JSX / Haxe / TypeScriptJSX / Haxe / TypeScript
JSX / Haxe / TypeScript
 
ぼくのかんがえたさいきょうのLL
ぼくのかんがえたさいきょうのLLぼくのかんがえたさいきょうのLL
ぼくのかんがえたさいきょうのLL
 
F#の基礎(嘘)
F#の基礎(嘘)F#の基礎(嘘)
F#の基礎(嘘)
 
関数型言語のすすめ
関数型言語のすすめ関数型言語のすすめ
関数型言語のすすめ
 
C#(VB)プログラマのためのF#入門
C#(VB)プログラマのためのF#入門C#(VB)プログラマのためのF#入門
C#(VB)プログラマのためのF#入門
 
F#によるFunctional Programming入門
F#によるFunctional Programming入門F#によるFunctional Programming入門
F#によるFunctional Programming入門
 
自分戦略
自分戦略自分戦略
自分戦略
 
SI屋のためのF# ~DSL編~
SI屋のためのF# ~DSL編~SI屋のためのF# ~DSL編~
SI屋のためのF# ~DSL編~
 
輪るビングドラム.NET
輪るビングドラム.NET輪るビングドラム.NET
輪るビングドラム.NET
 
基礎からのベイズ統計学 2章 勉強会資料
基礎からのベイズ統計学 2章 勉強会資料基礎からのベイズ統計学 2章 勉強会資料
基礎からのベイズ統計学 2章 勉強会資料
 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented Programming
 
基礎からのベイズ統計学 輪読会資料 第1章 確率に関するベイズの定理
基礎からのベイズ統計学 輪読会資料 第1章 確率に関するベイズの定理基礎からのベイズ統計学 輪読会資料 第1章 確率に関するベイズの定理
基礎からのベイズ統計学 輪読会資料 第1章 確率に関するベイズの定理
 
統計学の基礎の基礎
統計学の基礎の基礎統計学の基礎の基礎
統計学の基礎の基礎
 

Similar a 解説?FSharp.Quotations.Compiler

Power shell で DSL
Power shell で DSLPower shell で DSL
Power shell で DSL
urasandesu
 
関数型言語ElixirのIoTシステム開発への展開
関数型言語ElixirのIoTシステム開発への展開関数型言語ElixirのIoTシステム開発への展開
関数型言語ElixirのIoTシステム開発への展開
Hideki Takase
 
Dalvikバイトコードリファレンスの読み方 改訂版
Dalvikバイトコードリファレンスの読み方 改訂版Dalvikバイトコードリファレンスの読み方 改訂版
Dalvikバイトコードリファレンスの読み方 改訂版
Takuya Matsunaga
 
スタート低レイヤー #0
スタート低レイヤー #0スタート低レイヤー #0
スタート低レイヤー #0
Kiwamu Okabe
 
WTM53 phpフレームワーク いまさらcodeigniter
WTM53 phpフレームワーク いまさらcodeigniterWTM53 phpフレームワーク いまさらcodeigniter
WTM53 phpフレームワーク いまさらcodeigniter
Masanori Oobayashi
 
F#のコンピュテーション式
F#のコンピュテーション式F#のコンピュテーション式
F#のコンピュテーション式
pocketberserker
 

Similar a 解説?FSharp.Quotations.Compiler (20)

Power shell で DSL
Power shell で DSLPower shell で DSL
Power shell で DSL
 
2009年のPHPフレームワーク
2009年のPHPフレームワーク2009年のPHPフレームワーク
2009年のPHPフレームワーク
 
今からでも遅くないC#開発
今からでも遅くないC#開発今からでも遅くないC#開発
今からでも遅くないC#開発
 
コンピュテーション式ハンズオン
コンピュテーション式ハンズオンコンピュテーション式ハンズオン
コンピュテーション式ハンズオン
 
関数型言語ElixirのIoTシステム開発への展開
関数型言語ElixirのIoTシステム開発への展開関数型言語ElixirのIoTシステム開発への展開
関数型言語ElixirのIoTシステム開発への展開
 
第2回勉強会スライド
第2回勉強会スライド第2回勉強会スライド
第2回勉強会スライド
 
C++0x総復習
C++0x総復習C++0x総復習
C++0x総復習
 
(ゲームじゃない方の)switchで遊びたい話
(ゲームじゃない方の)switchで遊びたい話(ゲームじゃない方の)switchで遊びたい話
(ゲームじゃない方の)switchで遊びたい話
 
PHPBLT#6 PHPの未来に入るかもしれない機能の紹介
PHPBLT#6 PHPの未来に入るかもしれない機能の紹介PHPBLT#6 PHPの未来に入るかもしれない機能の紹介
PHPBLT#6 PHPの未来に入るかもしれない機能の紹介
 
Yaminabe fortran
Yaminabe fortranYaminabe fortran
Yaminabe fortran
 
C#勉強会
C#勉強会C#勉強会
C#勉強会
 
Dalvikバイトコードリファレンスの読み方 改訂版
Dalvikバイトコードリファレンスの読み方 改訂版Dalvikバイトコードリファレンスの読み方 改訂版
Dalvikバイトコードリファレンスの読み方 改訂版
 
Python におけるドメイン駆動設計(戦術面)の勘どころ
Python におけるドメイン駆動設計(戦術面)の勘どころPython におけるドメイン駆動設計(戦術面)の勘どころ
Python におけるドメイン駆動設計(戦術面)の勘どころ
 
スタート低レイヤー #0
スタート低レイヤー #0スタート低レイヤー #0
スタート低レイヤー #0
 
元運用担当者が,現役時代に本当に欲しかったもの. Osc2014 kansai@kyoto terraform introduction
元運用担当者が,現役時代に本当に欲しかったもの. Osc2014 kansai@kyoto terraform introduction元運用担当者が,現役時代に本当に欲しかったもの. Osc2014 kansai@kyoto terraform introduction
元運用担当者が,現役時代に本当に欲しかったもの. Osc2014 kansai@kyoto terraform introduction
 
WTM53 phpフレームワーク いまさらcodeigniter
WTM53 phpフレームワーク いまさらcodeigniterWTM53 phpフレームワーク いまさらcodeigniter
WTM53 phpフレームワーク いまさらcodeigniter
 
F#のコンピュテーション式
F#のコンピュテーション式F#のコンピュテーション式
F#のコンピュテーション式
 
PHP7をDockerで動かしたという話
PHP7をDockerで動かしたという話PHP7をDockerで動かしたという話
PHP7をDockerで動かしたという話
 
Ruby で ffmpeg の filter_complex と戯れる話
Ruby で ffmpeg の filter_complex と戯れる話Ruby で ffmpeg の filter_complex と戯れる話
Ruby で ffmpeg の filter_complex と戯れる話
 
Ruby で ffmpeg の filter_complex と戯れる話
Ruby で ffmpeg の filter_complex と戯れる話Ruby で ffmpeg の filter_complex と戯れる話
Ruby で ffmpeg の filter_complex と戯れる話
 

Más de bleis tift

yield and return (poor English ver)
yield and return (poor English ver)yield and return (poor English ver)
yield and return (poor English ver)
bleis tift
 
F#で始めるスマートフォンアプリ
F#で始めるスマートフォンアプリF#で始めるスマートフォンアプリ
F#で始めるスマートフォンアプリ
bleis tift
 
SCMBC Git入門セッション発表資料
SCMBC Git入門セッション発表資料SCMBC Git入門セッション発表資料
SCMBC Git入門セッション発表資料
bleis tift
 
CIのその先へ
CIのその先へCIのその先へ
CIのその先へ
bleis tift
 

Más de bleis tift (14)

PCさえあればいい。
PCさえあればいい。PCさえあればいい。
PCさえあればいい。
 
テストの自動化を考える前に
テストの自動化を考える前にテストの自動化を考える前に
テストの自動化を考える前に
 
札束でExcelを殴る
札束でExcelを殴る札束でExcelを殴る
札束でExcelを殴る
 
yield and return (poor English ver)
yield and return (poor English ver)yield and return (poor English ver)
yield and return (poor English ver)
 
現実(えくせる)と戦う話
現実(えくせる)と戦う話現実(えくせる)と戦う話
現実(えくせる)と戦う話
 
ラムダでウィザード 滅せよ手続き、とチャーチは言った (※言ってません)
ラムダでウィザード 滅せよ手続き、とチャーチは言った (※言ってません)ラムダでウィザード 滅せよ手続き、とチャーチは言った (※言ってません)
ラムダでウィザード 滅せよ手続き、とチャーチは言った (※言ってません)
 
async/await不要論
async/await不要論async/await不要論
async/await不要論
 
VBAを書きたくない話(Excel-DNAの紹介)
VBAを書きたくない話(Excel-DNAの紹介)VBAを書きたくない話(Excel-DNAの紹介)
VBAを書きたくない話(Excel-DNAの紹介)
 
F#で始めるスマートフォンアプリ
F#で始めるスマートフォンアプリF#で始めるスマートフォンアプリ
F#で始めるスマートフォンアプリ
 
SCMBC闇LT資料
SCMBC闇LT資料SCMBC闇LT資料
SCMBC闇LT資料
 
SCMBC Git入門セッション発表資料
SCMBC Git入門セッション発表資料SCMBC Git入門セッション発表資料
SCMBC Git入門セッション発表資料
 
SCM Boot Camp
SCM Boot CampSCM Boot Camp
SCM Boot Camp
 
Vim再入門
Vim再入門Vim再入門
Vim再入門
 
CIのその先へ
CIのその先へCIのその先へ
CIのその先へ
 

解説?FSharp.Quotations.Compiler