Почему в C # нет лексически вложенных функций? - PullRequest
12 голосов
/ 23 февраля 2009

Почему разработчики языка C # не включили поддержку чего-то подобного (перенесено из Структура и интерпретация компьютерных программ , второе издание, стр. 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);
}

Ответы [ 2 ]

36 голосов
/ 23 февраля 2009

На самом деле, 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);
}
8 голосов
/ 23 февраля 2009

Как сказал Джастис, вы можете сделать это с C # 3.5 и лямбдами; если у вас есть 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...