Microsoft Research F# 1.9.1.9

| コメント(0) | トラックバック(0)

最近、F# で遊んでいます。F# というのは Microsoft Research で研究されている ML 言語の亜種です。ML というのは最初期の関数型言語とされています。関数型言語というのは字面の定義では状態をもたない言語です。単純に言えば破壊的な代入などを持たないとされています。Wikipedia の関数型言語の項では

  • APL
  • CLOS
  • ConcurrentClean
  • F#
  • Haskell
  • LISP
  • ML
  • OCaml
  • Scheme
  • XSLT

が挙げられています。

便利な点としては、副作用が少ないため (すべての関数型言語がまったく副作用を持たないわけではない) 並列化という方向性とミックスしやすいのだと考えます。実際最近、話題になっている Erlang も並列化という観点からです。

とりあえず、テストとして階乗を計算してみました。

let rec fact x =
if (x <= 1) then 1 else (x * fact (x - 1));;
let answer = fact 5;;
let computeAnswer() = System.Console.WriteLine(answer)
let main = computeAnswer()
Code. 1: Sample 1

OCaml のサンプルコードを元にしてみました。これを末尾再帰に気をつけて手直しすると以下のようになります。

let rec fact x r =
if (x <= 1) then r else (fact (x - 1) (r * x));;
let answer = fact 5 1;;
let computeAnswer() = System.Console.WriteLine(answer)
let main = computeAnswer()
Code. 2: Sample 2

これらのコードは OCaml プログラミング入門を参考にしました。

この 2 つのコードを IL レベルで比較してみます。

  .method public static int32  fact(int32 x) cil managed
  {
    // コード サイズ       21 (0x15)
    .maxstack  5
    IL_0000:  ldarg.0
    IL_0001:  ldc.i4.1
    IL_0002:  cgt
    IL_0004:  ldc.i4.1
    IL_0005:  xor
    IL_0006:  brfalse.s  IL_000a

    IL_0008:  ldc.i4.1
    IL_0009:  ret

    IL_000a:  ldarg.0
    IL_000b:  ldarg.0
    IL_000c:  ldc.i4.1
    IL_000d:  sub
    IL_000e:  call       int32 Test::fact(int32)
    IL_0013:  mul
    IL_0014:  ret
  } // end of method Test::fact
Code. 3: Sample 1 の IL
  .method public static int32  fact(int32 x,
                                    int32 r) cil managed
  {
    // コード サイズ       22 (0x16)
    .maxstack  5
    IL_0000:  ldarg.0
    IL_0001:  ldc.i4.1
    IL_0002:  cgt
    IL_0004:  ldc.i4.1
    IL_0005:  xor
    IL_0006:  brfalse.s  IL_000a

    IL_0008:  ldarg.1
    IL_0009:  ret

    IL_000a:  ldarg.0
    IL_000b:  ldc.i4.1
    IL_000c:  sub
    IL_000d:  ldarg.1
    IL_000e:  ldarg.0
    IL_000f:  mul
    IL_0010:  starg.s    r
    IL_0012:  starg.s    x
    IL_0014:  br.s       IL_0000
  } // end of method Fact::fact
Code. 4: Sample 2 の IL

Code. 3 と Code. 4 を比較すると、Code. 4 がループになっているのに対し、Code. 3 は再帰呼び出しのままであることがわかります。F# でも末尾再帰な関数呼び出しにすることでより最適なコード生成が行われるようです。

トラックバック(0)

トラックバックURL: http://www.cworld2000.com/cgi-bin/mt/mt-tb.cgi/289

コメントする

Recent Tracks

gorn708's Profile Page

このブログ記事について

このページは、gornが2007年5月16日 22:26に書いたブログ記事です。

ひとつ前のブログ記事は「IDOLM@STER XENOGLOSSIA #05: 冷たい手、温かい手」です。

次のブログ記事は「BOMBERMAN LIVE」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Adwords