Войти в систему

Home
    - Создать дневник
    - Написать в дневник
       - Подробный режим

LJ.Rossia.org
    - Новости сайта
    - Общие настройки
    - Sitemap
    - Оплата
    - ljr-fif

Редактировать...
    - Настройки
    - Список друзей
    - Дневник
    - Картинки
    - Пароль
    - Вид дневника

Сообщества

Настроить S2

Помощь
    - Забыли пароль?
    - FAQ
    - Тех. поддержка



Пишет kouzdra ([info]kouzdra)
@ 2013-03-14 15:33:00


Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Entry tags:Идиоты, История города Глупова

Для чего нужны замыкания:
Я это потому что кажется не все понимают что это такое и зачем. Паргентум это пример "человека от сохи", который просто не в курсе "куда очки надевать", но есть предположение, что не он только не вполне понимает - бо мифологии вокруг данной конструкции разведено изрядно:

[info]pargentum@lj жжот:

Ваш пример демонстрирует, что замыкание - как и многие другие технические и языковые решения в ФП - это решение для, мягко говоря, надуманной проблемы

(это он про high-order функции на примере композиции:

proc compose = ((real) real f, (real) real g) (real) real:
    (real x) real: f (g (x))

при попытке написать что-то вроде compose (sin, cos) (3.1415)

вывалится с segfault. Ну или может не вывалится - если стек затереться не успеет.

Но то полбеды - а началось это с рассуждения о том, что Если контекст замыкания - не переменные, то в чем вообще сакральный смысл замыкания и чем оно отличается от дополнительных (скрытых) параметров?

(там впрочем поперло уже вовсе смешное - в духе "а мы сами знаем что на ассмеблере писать плохо - мы все в кодах пишем")

Так вот - замыкания (АКА closures) нужны чтобы это работало:

# include <functional>
# include <iostream>
# include <math.h>

using namespace std;

template <typename T>
function<T (T)>  compose (function<T (T)> f, function<T (T)> g) {
  return [=](T x) { return f (g (x)); };
}

int main () {
  cout << "sin (cos (2*pi)=" << compose<double> (sin, cos) (2*3.1415) << "\n";
  return 0;
}


А вот кстати для такого:

template <typename T>
void scan (T a [], int const len, function<void (T)> f) {
  for (int i = 0; i != len; ++ i)
    f (a [i]);
}

int main () {
  double n [] = { 1, 2, 3, 4, 5 };
  double res = 0;
  scan<double> (n, sizeof (n)/sizeof (*n), [&res](double x) { res += x*x; });
  cout << res << "\n";
  return 0;
 }

Замыкания как раз ни на фиг не нужны - привет [info]pargentum@lj с его "ужастными переменными" - это прекрасно работало и в А-60 и в Паскале (только не "турбо") и много где еще - включая старые версии gcc - без всяких замыканий - тут как раз вполне достаточно поддержки динамической цепочки вызовов.


(Добавить комментарий)


[info]dorkavla
2013-03-15 15:18 (ссылка)
А чаво, без умных слов типа "замыкание" и "FP" оно не работает?
Ну композиция, ну синус от косинуса, и чаво?

(Ответить) (Ветвь дискуссии)


[info]kouzdra
2013-03-15 15:28 (ссылка)
Ну так либо оно работает либо нет. Умные слова про "замыкание" собственно знать нужно лишь при разговоре с теми, кто не понимает, что оно может и не сработать.

А так техника конечно - как и static-single-assignment-form.

(Ответить) (Уровень выше)