F#とは
F#とは、OCamlをさらに発展させた "関数型とオブジェクト指向をあわせもつマルチパラダイム言語" です。 また、C#やVisual Basicなどの.NET言語との相互運用性があり、.NETの利用・開発が容易に可能となっています。
関数型プログラミング言語、または関数型言語というものを聞いたことがない方もいると思います。
関数型プログラミングは、関数や式を宣言していくという手法でコーディングしていきます(= 宣言型プログラミング)。 近年オブジェクト指向言語にも取り入れ始められている "ラムダ式" も、この関数型プログラミングの機能の一つです。
関数型プログラミング言語は、このラムダ式とも縁が深い "ラムダ計算論" の考え方を利用してプログラムを記述していきます。 ここでは詳細を書くことは避けますが、興味がある方は調べてみるのもいいかもしれません。
2019年1月現在、世の中はオブジェクト指向プログラミング言語が覇権を握っています。しかし、徐々に関数型言語も認知度を広めてきました。
F#においては、2019年1月現在、そこまで認知度は高くありませんし、人気もそこまでありません。 これは一重に.NET上で動く言語として、C#とかいう最強のライバルがいるせいだと思います。わざわざ関数型言語とかいう得体のしれないものを使うくらいならば、 使い慣れているオブジェクト指向言語を使ったほうがいいですからね(しかもC#は完成度が高い)。
しかし、F#にはF#のいいところがあります。もう少し言うならば、関数型言語にはオブジェクト指向言語にはない、良いところがたくさんあります。
その一端でもこの記事を通して紹介できればと思います。
Hello, World
まずはすべてのプログラミング言語の登竜門である "Hello, World!!" のF#版を見てみましょう。
上記のコードを簡単に見ていきましょう。また、各項目の詳細は別ページにて解説しています。わからないことがあっても理解する必要はありません。読み飛ばしてしまってください。
関数
F#では、"関数" を中心にプログラムを作成していきます。
F#の関数宣言は以下のように、実にシンプルに行うことができます。
let 関数名 引数 = 処理
型の宣言や返り値の型宣言は必要ありません。これはF#に強力な型推論機能があるためです。しかし、必要とあれば型宣言をすることも可能です。その場合は、以下のように宣言します。
let 関数名 (引数: 引数型名) : 返り値型名 = 処理
いくつか簡単なサンプルを見ていきましょう。
ここで unit型 という特殊な型が出てきました。これはC#でいうところの void に近いものですが同じものではありません。
unit型は特定の値がないことを示す型です。ちなみにC#の void型 は メソッドの文脈では "戻り値がない" ことを表現しますが、unit型の場合、"unit型の値" が返っているため、本質的には違うものです。
let束縛
F#では、他の言語のような変数(に似たもの)を宣言することができます。関数型言語では、これを俗に "ラベル" と呼んだりします。F#においては "let束縛" や "letバインディング" と呼びます。この説明ではよくとわからないと思いますので、詳細は別記事に委ねるとして、ここでは変数だと思っておいて構いません。しかし、別モノだという認識だけは頭の片隅にでも置いておいてください。
letバインディングを利用することによって、関数宣言や値の宣言をすることができます。以下に簡単な例を示します。
// '100' という int型 の値と, 'x' というラベルをバインディング(= 関連付け)する
let x = 100
// '200.5' という double型 の値と, 'y' というラベルをバインディングする
let y = 200.5
エントリポイント
F#プログラムが開始した際に、一番初めに呼び出される関数を "メイン関数" といいます。また、プログラムの開始地点という意味で "エントリポイント" とも言います。
エントリポイントには [<EntryPoint>] 属性を付与することで、それがメイン関数であることをコンパイラに知らせることができます。つまり、[<EntryPoint>] 属性さえついていれば、メイン関数の関数名は main でなくともよいということになります。
その他
今回のサンプルでは、"パイプライン(|>)" や "ラムダ式(fun)" なども同時に利用したものとしてみました。 それらの紹介をここでしてしまうと、とても長い文量となってしまうため、それ用の記事にて紹介したいと思います。