Skip to content

パラメータと値の命名規則

C#などの命令型言語からF#に移行すると、多くの場合、識別子が短く、難解に感じるかもしれません。

C#やJavaでは、長くて説明的な識別子を使うのがベストプラクティスです。一方、関数型言語では、関数名自体は説明的になることもありますが、関数内のローカル識別子は非常に短くなりがちです。また、パイプ処理や関数合成を多用して、コード行数を最小限に抑えます。

たとえば、素数のふるいの簡単な実装において、ローカル値に長く説明的な名前を使ったものを以下に示します。

let primesUpTo n =
// 再帰的な中間関数を作る
let rec sieve listOfNumbers =
match listOfNumbers with
| [] -> []
| primeP::sievedNumbersBiggerThanP->
let sievedNumbersNotDivisibleByP =
sievedNumbersBiggerThanP
|> List.filter (fun i-> i % primeP > 0)
// 再帰部分
let newPrimes = sieve sievedNumbersNotDivisibleByP
primeP :: newPrimes
// ふるいを使う
let listOfNumbers = [2..n]
sieve listOfNumbers // 戻り値
// テスト
primesUpTo 100

同じ実装を、より簡潔で慣用的な名前とコンパクトなコードで以下に示します。

let primesUpTo n =
let rec sieve l =
match l with
| [] -> []
| p::xs ->
p :: sieve [for x in xs do if (x % p) > 0 then yield x]
[2..n] |> sieve

暗号めいた名前が常に良いわけではありません。ただし、関数が数行に収まり、使う操作が標準的なものであれば、割と一般的な慣用表現です。

一般的な命名規則は以下のとおりです。

  • “a”、“b”、“c”などは型を表します。
  • “f”、“g”、“h”などは関数を表します。
  • “x”、“y”、“z”などは関数の引数を表します。
  • リストは末尾に”s”を付けて示します。つまり、 xs はxのリスト、 fs は関数のリストなどを表します。 x::xs はリストの先頭(最初の要素)と末尾(残りの要素)を意味し、非常によく見かける表現です。
  • _ は値を気にしない場合に使います。つまり、 x::_ はリストの残りを気にしないことを意味し、 let f _ = something はfの引数を気にしないことを意味します。

短い名前を使うもう一つの理由は、多くの場合、意味のある名前を付けられないためです。たとえば、パイプ演算子の定義は次のようになります。

let (|>) x f = f x

fxが何になるかはわかりません。fはどんな関数にもなり得るし、xはどんな値にもなり得ます。これを明示的にしても、コードの理解度は上がりません。

let (|>) aValue aFunction = aFunction aValue // これで良くなったといえますか?

このサイトでは両方のスタイルを使います。入門シリーズでは、ほとんどの概念が新しいため、中間値や長い名前を使った非常に説明的なスタイルを使います。しかし、より高度なシリーズでは、スタイルはより簡潔になります。