Почему у С# нет лексически вложенных функций?
Почему разработчики языка С# не могли включить поддержку чего-то вроде этого (портировано из Структура и интерпретация компьютерных программ, вторая редакция, стр. 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);
}
Ответы
Ответ 1
Фактически, С# имеет именно это.
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
Подобно правосудию, вы можете сделать это с С# 3.5 и лямбдами; если у вас есть С# 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 не определен в С# 2.0, поэтому вы должны определить его самостоятельно:
public delegate TResult Func<T, TResult>(T guess);