Геолог-анархист
я либо убер пьян, либо ультра туп.
нифига не понимаю замыкание
может мне кто-нибудь это на пальцах объяснить?
я либо убер пьян, либо ультра туп.
нифига не понимаю замыкание
может мне кто-нибудь это на пальцах объяснить?
Это функция, которая использует внешнюю переменную - именно внешнюю, а не передаваемую через параметры.
Только это вроде как плохой стиль - понятность и читаемость кода ухудшается.
Или я отстал от жизни ?
Пример практически тот же, что и в вики :
int x = 10;
int func1(int y) // тут есть замыкание
{
return x+y;
}
int func2(int x, int y) // а тут нет
{
return x+y;
}
(я вики раза два прочитал. примеры кодов разобрал, но все равно на голове не уложилось, что это и нахрена надо.)
не обязательно глобальная - т.е. не переменная самого верхнего уровня, а просто внешняя - т.е. переменная, которая определена на уровень или несколько уровней выше, и , как следствие, видна в пространстве имен вложенной функции без объявления...
глобальная - это всё таки когда выше уровня нет
а функция может быть вложена одна в другую - это не существенно, возможно, в данном случае, но разница есть...
основной смысл в том, что используется переменная, явно не определенная и не переданная через параметры - вроде так.
только так делать не стоит - не вижу смысла - экономия писанины мизерная, а вернешься к коду через неделю, или не дай бог, через год, и нихрена не поймёшь
по ходу понять и прочувствовать поможет только написание примеров.
ведь для чего-то это замыкание придумали? не для того ж, чтоб экономить при вызове один аргумент, имея после этого кучу гемороя с поддержкой кода.
да судя по всему, мой вопрос дюже нубовский. есть подозрение, что регистрироваться, чтобы задать его - лучший способ нарваться на молчание(в лучшем случае) или смехуёчки да пиздахаханьки.
Тут вон спрашивают в соседнем сообществе, как устроена девственная плева - и вежливо получают ответы и пожелания удачи
Люди становятся добрее, чтоли
а вот как устроена девственная плева я, кстати, так и не знаю. сообщество анатомов/антропологов было? ,) или просто вопрос из серии "чо с ней делать?" ? ,)))
Ну тока это.. не обижайте маленьких
>>не обижайте маленьких
там народ и так оторвался =)
но в целом оборжали по-доброму так. не зло. даже удивлен.
Замыкание растёт из языков вроде лиспа, и уж там используется в хвост и гриву. Приведу примеры на диалекте лиспа, который так и называется, Clojure («зомыканее»).
(defn kuku [x y] (+ x y))
Эта строчка определяет функцию kuku, которая берёт два аргумента x и y и возвращает их сумму (+ x y). Здесь никаких замыканий нет.
(defn kuku1 [x] #(+ x %))
Эта строчка определяет функцию kuku1, которая берёт один аргумент x и возвращает безымянную функцию #(+ x %). Вот эта безымянная функция и есть замыкание. Она берёт один аргумент y (или называй его как хочешь, здесь название переменной можно не указывать) и возвращает (+ x y).
Это как сопряжённые пространства в математике. Например, бра-кет в квантовой механике: можно рассматривать <ψ|φ> как функцию от двух аргументов ψ и φ, а можно как функцию <ψ| от одного аргумента |φ>.
Ну и вообще функцию от эн аргументов всегда можно переписать как функцию одного аргумента, возвращающую функцию от эн минус одного аргумента.
(defn make-counter [] (let [x (atom -1)] #(swap! x inc)))
Вот мы определили функцию make-counter, которая никаких аргументов не берёт, создаёт переменную x, равную минус единице, и возвращает безымянную функцию #(swap! x inc), которая при каждом вызове увеличивает x на один и возвращает. Вот мы даём ей имя:
(def c1 (make-counter))
Вызываем (c1). Она возвращает 0. Вызываем ещё раз. Возвращает 1. Вызываем ещё раз. Возвращает 2. И так далее.
(def c2 (make-counter))
Вызываем (c2), возвращает 0. Ещё раз. 1. Вызываем (+ (c1) (c2)). Возвращает 5. Вызываем ещё раз. Возвращает 7. Ещё раз. 9. И так далее.
А вот так такой же счётчик выглядит на common lisp, тоже через замыкание (из какой-то пдфки на просторах интернета):
(defun make-counter ()
(let ((x -1))
(lambda () (setq x (+ x 1)))))
BlindPew Это, уважаемый, теперь называется не "плохой стиль", а "модное функциональное программирование", ага )))
Допустим, в разделе "ссылки" в википедийной статье есть чудная статья - habrahabr.ru/blogs/webdev/38642/
Там есть примеры.
Но вопрос-то в другом стоит, если я правильно понимаю. Примеров дохера, вопрос - как ООП-щику понять, зачем нужно замыкание? Ответ - никак. ООП-щику оно не надо. Чтобы замыкание заиграло смыслом, надо чтобы язык этому способствовал. В русском нет артиклей, но есть окончания. В английском - наоборот. Как объяснить русскому, зачем использовать артикли? Пока он говорит по-русски - незачем.
1. Область видимости. У ООПа для этого есть классы и область видимости. В javasсript нет классов. И чтобы спрятать переменную от другого скрипта, я могу разве что в замыкание ее спрятать.
2. Связи между объектами (контекст исполнения). В ООПе все просто - есть кнопка, по кнопке щелкнули, в обработчике есть обращение к this. Что такое this? Правильно, кнопка, объект, у нас же объектно-ориентированный язык. В функциональном языке этим this скорее всего окажется... сама функция-обработчик. Чо делать? Ага, перед определением обработчика написать var context = this;, где this - это кнопка. И в обработчике обращаться к context, сохраненному замыканием.
Вот эти примеры все в википедии - нафига человеку создавать "специализированную функцию из более общей"?
Там пример на Lua замечательный. Функция "плюсователь_на_два".
Зачем такое делать?
Ну был бы у меня ООП, я б двойку передал в конструктор и сохранил в приватной переменной. И при вызове метода к параметру прибавлял бы эту приватную переменную.
А в жабаскрипте у меня нету классов. Нет приватных переменных. Есть замыкание. Вот и извращаюсь как могу, да.
>>хорошо бы пример из жизни. когда замыкание - лучший способ решить задачу.
Замыкание - это, чаще всего, не "лучший способ решить задачу". Чаще - единственно возможный из-за синтаксиса языка. Иногда - более краткий с точки зрения синтаксиса. Но чтобы "лучший" - хм...
а вот теперь идеология кристальная ясна.
тебе надо преподавательствовать или учебники писать. =)
Сложить ООП и замыкания можно. Но особой потребности в этом, чаще всего, нет. Да, есть случаи, когда это экономит пол страницы кода. Но чтобы без этого "не жить" - нееее.