【问题标题】:Why doesn't C# have lexically nested functions?为什么 C# 没有词法嵌套函数?
【发布时间】:2009-02-23 02:39:40
【问题描述】:

为什么 C# 语言设计者可能不包含对此类内容的支持(来自 Structure and Interpretation of Computer Programs,第二版,第 30 页):

/// <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);
}

【问题讨论】:

    标签: c# scheme


    【解决方案1】:

    事实上,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);
    }
    

    【讨论】:

    • 是的,C# 不会将尾递归优化为循环。 该语言缺少该功能。
    • 感谢您指出这一点!我将不得不推动切换到 .NET 3.5(我们莫名其妙地仍在使用 2.0)。
    • 当您使用它时,您应该推动切换到 Haskell。但是.net-3.5 也不错!
    • 嗯为什么你有那个默认的东西而不是直接初始化?
    • @Steve C#2 具有内部匿名函数;我不确定它是否关闭。 @leppie 它具有真正的 lexically 范围闭包,因为变量的 names 是封闭的,而不是它们的 values。 (无论如何,这是最常见的抱怨。如果您的不同,请解释。)
    【解决方案2】:

    正如Justice 所说,您可以使用C# 3.5 和lambdas 来做到这一点;如果你有 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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-16
      • 2010-09-29
      • 1970-01-01
      • 2022-01-10
      • 1970-01-01
      • 2011-05-10
      相关资源
      最近更新 更多