2009-02-23 8 views
12

なぜC#の言語設計者はこのような何かのためのサポート含まれていない可能性があります(Structure and Interpretation of Computer Programsから移植された、第二編、P 30。。):実際にC#に字句的にネストされた関数がないのはなぜですか?

/// <summary>Return the square root of x.</summary> 
double sqrt(double x) { 
    bool goodEnough(double guess) { 
    return Math.Abs(square(guess) - x) < 0.001; 
    } 
    double improve(double guess) { 
    return average(guess, x/guess); 
    } 
    double sqrtIter(double guess) { 
    return goodEnough(guess) ? guess : sqrtIter(improve(guess)); 
    } 
    sqrtIter(1.0); 
} 

答えて

36

、C#が正確にこれを持っています。

double sqrt(double x) { 
    var goodEnough = new Func<double, bool>(guess => 
     Math.Abs(square(guess) - x) < 0.001 
    ); 
    var improve = new Func<double, double>(guess => 
     average(guess, x/guess) 
    ); 
    var sqrtIter = default(Func<double, double>); 
    sqrtIter = new Func<double, double>(guess => 
     goodEnough(guess) ? guess : sqrtIter(improve(guess)) 
    ); 
    return sqrtIter(1.0); 
} 
+2

+1。適切なテール再帰部分を除いて。 :) –

+1

うん、C#はテール再帰をループに最適化しません。 *その*機能は言語にはありません。 – yfeldblum

+0

これを指摘してくれてありがとう!私は.NET 3.5への切り替えを押し進める必要があります(われわれはまだ2.0を使っていません)。 –

8

Justiceが言ったように、あなたはC#3.5とlambdaでそれを行うことができます。あなたがC#2.0を持っている場合、それはやや少ないセクシーになりますが、あなたは、無名関数を使用することができます。

double sqrt(double x) { 
    Func<double, bool> goodEnough = delegate(double guess) { 
     return Math.Abs(square(guess) - x) < 0.001; 
    }; 
    Func<double, double> improve = delegate(double guess) { 
     return average(guess, x/guess); 
    }; 
    Func<double, double> sqrtIter = null; 
    sqrtIter = delegate(double guess) { 
     return goodEnough(guess) ? guess : sqrtIter(improve(guess)); 
    }; 
    return sqrtIter(1.0); 
} 

編集:私はのFuncは、C#2.0で定義されていない、忘れてしまったので、あなたはそれを自分で定義する必要があります:

public delegate TResult Func<T, TResult>(T guess); 
関連する問題