※このエントリは F# Advent Calendar jp 2010 第17回目の参加記事です。
F#の話題を目にしても「何やら難しそうなコードが掲載されていて、自分には関係なさそうだ」と素通りしたことはないでしょうか?実は、私もそうでした。F#の本を入手してぱらぱら眺めてから、2年近くまともに使わずに放置しました。
ところでよく「C#とVB.NETは文法が違うだけで中身はほぼ同じ」と言われます。F#もあまり関数型の側面を強調しないで、VB.NETと同列に捉えてみるのも一つの手です。そんなわけで、C#使いの方へF#変換プログラムのクリスマスプレゼントです(間に合いませんでしたが・・・)。
- ソース ⇒ https://github.com/7shi/cs2fs (public domain)
何だこれ、C#で書かれているじゃないか!F#のエントリとしては画竜点睛を欠くんじゃないか? ―― いえ、ちょっと待ってください。
C#からF#に変換できるんだから、自分自身を変換してしまえば済みます!
というわけでこちらが本物(?)の、C#からF#に変換するプログラムです。Silverlight化したためブラウザ上で実行できます。
- 実行 ⇒ http://7shi.net/cs2fs/
- ソース ⇒ https://bitbucket.org/7shi/cs2fs/src (public domain)
本来Visual Studio上でF# Silverlightプロジェクトを作成するにはVisual Studio 2010 Professional以上が必要ですが、今回はid:n7shi:20100710の方法によりフリーのVisual Web Developer 2010 Expressで作成しました。
余談
言語処理系は自分自身を処理(いわゆるセルフホスティング)できることが望ましいと思い、変換プログラムはC#自身で書きました。しかしこの方法論では新言語の開発で卵と鶏問題が発生します。対処方法として、まず既存の言語で新言語(最低限の言語仕様)から既存の言語への変換プログラムを実装して、次に本番の処理系を新言語自身で実装するという方法があります。後者の実装度が前者を追い抜けば、以後は変換なしで自分自身を処理できます。この方法の例として、SqueakはC言語へのトランスレータから出発したそうです。
制限事項
どんなC#のコードでも変換できるわけではありません。
- ループ中での break, continue は使用不可
- for は使用不可
- foreach は使えるため以下で代用
- foreach (var i in Enumerable.Range(0, 100))
- return で関数を途中で抜けるのは不可
- 値を返すための return は可能。分岐がある場合、それぞれの分岐の最後でreturnする。
- メンバへのアクセスは必ず this. を経由して行う
- C# 3.0のラムダ式は使用不可
- フィールドの初期値は定義不可
- ++, += のように直接数値を書き換える演算子は使用不可
- a = a + 1; などで代用
- ローカル変数の宣言では必ずvarを使用(型推論必須)
- (その他多数)
変換プログラム自体、これらの制限事項を踏まえて記述されているため、自分自身の変換(セルフホスティング?)ができるというカラクリです。
いきなり実用を目指す
話を戻します。C#とF#で同じものが表現できるのなら、文法さえどうにかすればC#の代用としてF#を使い始めるというのも決して難しいことではありません。その一助として、今回のプログラムがお役に立てば幸いです。
とりあえずF#らしさとか機能とかは棚に上げ、まずは実用を目指して使い始めながら、徐々にF#らしい使い方を広げていけば良いのではないでしょうか・・・という甘いストーリーです。
しかしF#では意図的にフロー構造が制限されているため、C#と1対1でコードを置き換えることができません。いわゆる関数型の考え方に沿ったコードを書いてもらうためにこういう制限があります。しかしこれも最初のうちは関数型がどうこうという小難しいことは棚に上げ、単純に機能が制限されたと捉えて、フローを工夫してみる所から始めるのもアリだと思います。具体的には、上の変換プログラムの制限事項が、この事情を反映しています。
参考資料など
実は変換プログラムを作る前から、同じような発想でC#を手動変換しながらF#を使っていました。当時のメモをまとめて、C#とF#を対訳にしたものを公開しています。
- F# - 七誌の開発Wiki (⇒ id:n7shi:20090722)
ちなみに手動で変換した最大のものはid:takuto_hさんの試作言語Yellowです。 (⇒ id:n7shi:20090720)
変換をしているうちにコツを覚えたので、段々とスクラッチから書けるようになってきました。この過程が私の考えている『いきなり実戦投入しながら慣れる』というイメージです。
まとまりがなくなりましたが、この記事が皆さんのF#ライフのきっかけになれば、これほど嬉しいことはありません。