![]() |
|
Модераторы: Sardar, Aliance |
![]()
|
|
| rene |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 43 Регистрация: 31.10.2006 Где: г. Висагинас, р. Литва Репутация: нет Всего: нет |
Всё-таки у меня есть сомнения насчёт того, что "closure" следует переводить как "замыкание".
Сначала мне думалось, что "closure" это сокрытие(от "close" - закрывать), так как оно скрывает, заключает в себя свой локальный контекст плюс ссылки на переменные внешней функции. Но потом меня начал терзать сомнения. Статья на Wikipedia Closure отсылает нас к модели актёра, в которой говориться, что "если актёр имеет адрес одного из других актёров, то они состоят в знакомстве. "Closure" имеет ссылки на переменные внешней функции, т.е. некая внутренняя анонимная функция знакома с внешней функцией. А "close" - это переводится, в том числе, как "близкий". Может "closure" корректней переводить как "приближение" или "близость"? Это сообщение отредактировал(а) rene - 18.11.2006, 21:51 |
|||
|
||||
| AKS |
|
|||
|
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
rene, действительно, замыкание нельзя назвать "дословным" переводом. Однако на "знакомство" англоязычные авторы этого понятия наверняка также не намекали.
На мой взгляд это понятие можно представлять как нечто (мы знаем, что в данном случае нечто - это функция-выражение), заключенное внутри чего-то, закрытое в чем-либо, находящееся в некоем замкнутом пространстве. Вообще ведь очень многие вещи дословно не переводятся, и их остается только интерпретировать (ха, все к одному - javascript и все, что с ним связано, должно интерпретироваться ;) ). |
|||
|
||||
| Nicholas_S |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 486 Регистрация: 12.10.2006 Где: Санкт-Петербург Репутация: 5 Всего: 19 |
В принципе, можно так и называть - клаузы. Есть такое компьютерное понятие (словарное). Понятие "клаузы" используется, в основном, в понятии предложений, например, в языке Prolog. Я думаю, тут можно тоже так же обозначать эти самые clauses.
-------------------- ...все в мире относительно |
|||
|
||||
| SelenIT |
|
|||
![]() баг форума ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3996 Регистрация: 17.10.2006 Где: Pale Blue Dot Репутация: 49 Всего: 401 |
Nicholas_S, clauses != closures ;)
-------------------- Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму! |
|||
|
||||
| Nicholas_S |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 486 Регистрация: 12.10.2006 Где: Санкт-Петербург Репутация: 5 Всего: 19 |
Посмотри в словаре, слова имеют равноправные значения, за исключением того, то у closure их чуть больше
Хотя написать мне стоило, конечно же, closure, а не clauses. -------------------- ...все в мире относительно |
|||
|
||||
| SelenIT |
|
|||
![]() баг форума ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3996 Регистрация: 17.10.2006 Где: Pale Blue Dot Репутация: 49 Всего: 401 |
Nicholas_S, в каком словаре такое можно увидеть? Смотрю в lingvo.yandex: clause, closure. Где хоть одно общее значение? -------------------- Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму! |
|||
|
||||
| Zeroglif |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
Вполне привычный перевод в математике... В функции могут обитать связанные идентификаторы (коренное население) и могут быть свободные (мигранты). Вызов функции формирует контекст исполнения, с которым связаны первые (строго - вары, формальные параметры, имена вложенных функций), и по определению не могут быть связаны вторые. Мигранты мешают функции "закрыться" в себе (типа я в домике, тут только свои). Чтобы она закрылась нужно найти, откуда приехали чужие, с кем они связаны (где зарегистрированы). Для этого в ECMAScript реализован механизм поиска по окружению (милицейская проверка "scope chain"), где-то там в окружении функции регистрация должна быть найдена, а значит функция "замкнётся". Замыкание. SelenIT Русская "клауза", но не "clause"... http://www.multitran.ru/c/m.exe?t=1034517_2_1 Это сообщение отредактировал(а) Zeroglif - 18.11.2006, 03:18 |
|||
|
||||
| rene |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 43 Регистрация: 31.10.2006 Где: г. Висагинас, р. Литва Репутация: нет Всего: нет |
Нет, всё-таки не понимаю почему "замкнётся"? И "модель актера" на это наводит. Это сообщение отредактировал(а) rene - 18.11.2006, 21:50 |
|||
|
||||
| Zeroglif |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
Функция, не содержащая свободных идентификаторов, считается замкнутой. Аксиома. Ибо на то она и чёрный ящик, локальность ей дороже денег. В Javascript функции равноправны с другими значениями и могут летать туда-сюда. Во время этих полётов связанным идентификаторам будет всё нипочём, а вот свободным позарез нужно не потерять связь со своим домом, поэтому функция-замыкание берёт с собой в полёт контекст, который держит эту связь. С помощью контекста с точки зрения функционального программирования свободные идентификаторы можно посчитать связанными, а значит функция замыкается... |
|||
|
||||
| AKS |
|
|||
|
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
Не особо разбираясь в программерских терминах ("модель актера" и т.д.), хотел бы дополнить картину, вернувшись к "простому" переводу слова closure.
Одно из значений глагола close - это замыкать ток. Т.е., сунул два пальца в розетку - получил "два контекста" и короткое замыкание. С функциями процесс похож, только замыкание не короткое, а такое, что пока есть ссылки на inner-function - два контекста в памяти браузера, висят, как шаровая молния, сохраняя "напряжение", замкнувшись меж собой... ;) Вот такие у меня "электрические" ассоциации (в силу отсутствия математических и программерских)... Насчет "знакомства" - трудно судить, кто там с кем именно знаком. Inner-function, по идее, не знает об outer-function ничего, она знает лишь об идентификаторах внешней функции, и то только о тех, которые ее мы "заставляем" использовать. Так что "актеры" вроде бы не знают адресов друг друга... |
|||
|
||||
| 12345c |
|
|||
![]() Круглый ![]() ![]() ![]() ![]() Профиль Группа: Vingrad developer Сообщений: 2018 Регистрация: 26.12.2005 Где: наша не пропадала ? Репутация: 57 Всего: 101 |
Zeroglif, если в 2 словах, то замыкания внутренних функций происходят в момент высвобождения памяти внешней функцией при окончании её; и существуют, если только были присвоены внешним переменным? Больше никаких принципиальных моментов в замыканиях нет?
(А пока сушествует внешняя, то внутренние функции ведут себя как простые, имеющие ссылки на временные переменные внешней функции, равно как и ссылки на глобальные переменные.) Кстати, а что произойдёт, если сделаем delete var1; для глобальной переменной, используемой в некоторой функции? Замыкание или ошибочная ссылка? Добавлено @ 13:06 AKS, по терминам электротехники, пальцами "короткое" замыкание не сделаешь. сопротивление тела - десятки килоом. Короткое - когда низкоомное с эффектом сгорания проводов или предохранителей. Добавлено @ 13:13 уточню: замыкания-функции существуют, если определения внутренних функций были присвоены внешним, например, глобальным переменным:
|
|||
|
||||
| rene |
|
||||||
![]() Новичок Профиль Группа: Участник Сообщений: 43 Регистрация: 31.10.2006 Где: г. Висагинас, р. Литва Репутация: нет Всего: нет |
когда говорят о коротком замыкании в электричестве обычно используют слово "short", например: short circuit Добавлено @ 14:43
Извиняюсь за упрямство. Zeroglif:
Можно источник аксиомы? По моему разумению, если внутренняя функция имеет ссылки на переменные внешней функции, то есть она имеет их адреса, значит она с ней "знакома". Предпологаю, что перевод "closure" появился сначала в переводных книгах по Perl, где это слово было переведено, как "замыкание". Затем этот преревод перекочевал в другие переводы, где переводили по аналогии. |
||||||
|
|||||||
| AKS |
|
||||||||||
|
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
12345c,
А у меня и с электричеством поверхностное знакомство (как со всем остальным). Поэтому стараюсь чаще смайлики вставлять... ;)
Переменные нельзя удалить оператором delete. rene,
Я ведь не знаю об их "обычаях". Все беру из словаря (close - замыкать (ток)).
Все же она с ней "не знакома":
|
||||||||||
|
|||||||||||
| Zeroglif |
|
||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
Хорошо. Пусть будет Javascript сам по себе, "closure/замыкание" в функциональном программировании само по себе. Описание замыканий применительно к Javascript - это в некоторой степени притягивание устоявшейся терминологии за уши, с этим можно соглашаться, можно не соглашаться. По факту JS-сообщество (включая шишек-разработчиков) приняло этот термин, его использует, он быстрый, понятный, плюс-минус точно отражает суть. Протестовать против замыкания как термина так же бесполезно, как бороться с хешами, ассоциативными массивами, классами в ECMAScript. Называют и называют. Лично мне не сложно мысленно переложить механизм ECMAScript на рельсы функционального программирования - "замыкание", "свободные переменные", "связанные переменные" и т.п., так проще и самому понять и объяснить другим. Хотя мне же ближе по смыслу и духу терминология, принятая в очень хорошей книжке товарища Абельсона "Структура и интерпретация компьютерных программ" (.pdf), где это дело называется "модель вычислений с окружениями". Замыкание там не рассматривается с привычной нам стороны, ECMAScript-овая scope chain там можно сопоставить, как покадровое разбиение вычислений, где рулят пары, каждая пара - это объект плюс окружение...
Можно. Это из весьма уважаемой книжки товарища Филда "Функциональное программирование" (.djvu), несколько почти цитат (убрал лямбду, сократил текст) надёрганных оттуда (из разных мест, но даю одним блоком):
p.s. Обязательно кликните по всем трём ссылкам в тексте, это нужно прочитать. |
||||||
|
|||||||
| AKS |
|
||||
|
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
Zeroglif,
А почему "за уши"? Вроде бы все сходится:
|
||||
|
|||||
| AKS |
|
|||
|
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
Zeroglif, скачал "Функциональное программирование".djvu. А что за расширение и как к нему "подобраться"?
|
|||
|
||||
| Zeroglif |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
http://windjview.sourceforge.net/
Имхо, с одной стороны, нет принципиальной разницы в том, вернули функцию или она просто работает внутри. Всё тот же доступ к scope chain. Но с другой стороны, наибольший (наглядный) смысл "замыкания" приобретают именно после выхода из объемлющей функции, когда вложенная функция продолжает жить (может и не одна, а несколько под каждый вызов с разными значениями), переживая своё лексическое окружение. Поэтому D.Cornford связывает появление замыкания именно с жизнью после смерти:
|
||||
|
|||||
| SelenIT |
|
|||
![]() баг форума ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3996 Регистрация: 17.10.2006 Где: Pale Blue Dot Репутация: 49 Всего: 401 |
AKS, насколько я понимаю, это некий open-source'ный аналог PDF. Вот навскидку нашел 2 читалки: отдельная и плагин для браузера...
-------------------- Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму! |
|||
|
||||
| AKS |
|
||||
|
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
О, скачал WinDjView! Тольк читать страшно - "SECD-машина, ленивая SECD-машина". ;)
Zeroglif,
Очередной трюк. Почему переменная не получает атрибут { DontDelete }? Добавлено @ 20:00 Zeroglif, вот это да! Я и не знал, что eval такой "коварный" - можно даже функцию удалить:
Это сообщение отредактировал(а) AKS - 19.11.2006, 20:01 |
||||
|
|||||
| AKS |
|
|||
|
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
Zeroglif, с этим eval (evil as D.Crockford sad) надо бы разобраться:
|
|||
|
||||
| 12345c |
|
|||
![]() Круглый ![]() ![]() ![]() ![]() Профиль Группа: Vingrad developer Сообщений: 2018 Регистрация: 26.12.2005 Где: наша не пропадала ? Репутация: 57 Всего: 101 |
А относительно замыканий - их более точный перевод для западного читателя тогда - зомбированные функции, а для нашего - дубли по Стругацким. |
|||
|
||||
| Zeroglif |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
Потому что в первом случае переменная, а во втором - свободный идентификатор, который позже станет свойством global object, т.к. никому не принадлежит изначально. Все переменные в процессе конкретизации становятся свойствами определённого variable object с аттрибутом DontDelete (ECMAScript 10.2). Для кода eval при конкретизации переменных аттрибут DontDelete не задаётся (ECMAScript 10.2.2). Чей-то своевольный замысел... |
|||
|
||||
| 12345c |
|
||||||||
![]() Круглый ![]() ![]() ![]() ![]() Профиль Группа: Vingrad developer Сообщений: 2018 Регистрация: 26.12.2005 Где: наша не пропадала ? Репутация: 57 Всего: 101 |
Пример 2 - попытаемся удалить глобальную переменную, чтобы как-то зазомбировать на её значение.
(Ещё вопрос, никто не знает, чем перловые замыкания отличаются от JS?) Это сообщение отредактировал(а) 12345c - 20.11.2006, 02:06 |
||||||||
|
|||||||||
| Zeroglif |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
А чем простая функция отличается от "зомби"? Что первая, что вторая не знают есть переменная или нет, они только держат цепочку объектов, которую им нужно обойти, чтобы найти определённый идентификатор. А "с" условно говоря никогда и не было, есть только scope chain, функция деталей (имён, значений) не видит. Например, локальной переменной в момент определений вложенной функции и в момент её вызова изнутри может вообще не существовать.
|
||||
|
|||||
| Zeroglif |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
Богат русский язык на обороты. Если будет удалена переменная, то замыкание само собой её не найдёт, т.к. не найдёт свойства с таким именем в scope chain, никаких значений оно не запоминает. Нормальное поведение. По сему тут нужно или вставлять в scope chain дополнительный объект или передавать значение переменной во вложенную функцию, или создавать некое свойство в функции и работать уже с ним. В общем без переделки не обойтись. Например, так:
|
||||
|
|||||
| AKS |
|
|||
|
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
Zeroglif,
Ну вот, обломался я. Думал с утра в "следопыты" опять подамся, начну очередное "мини-исследование" с eval. А оказывается все давно "черным по белому"... Вообще, логично все получается - нельзя в момент экзекуции установить какие-либо внутрение атрибуты. |
|||
|
||||
| rene |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 43 Регистрация: 31.10.2006 Где: г. Висагинас, р. Литва Репутация: нет Всего: нет |
Попробывал изобразить "closure":
Это сообщение отредактировал(а) rene - 21.11.2006, 20:08 Присоединённый файл ( Кол-во скачиваний: 26 )
closure.jpg 23,84 Kb |
|||
|
||||
| Zeroglif |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
Наглядно. А в какой программе можно быстро и удобно строить такие схемы как эти: http://billhails.net/Book/closure-captures-env-n.png http://billhails.net/Book/closure-extends-env-n.png кстати, это замыкание, так что не оффтоп |
|||
|
||||
| SelenIT |
|
|||
![]() баг форума ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3996 Регистрация: 17.10.2006 Где: Pale Blue Dot Репутация: 49 Всего: 401 |
Zeroglif, а у меня наверное оффтоп, но очень-очень близкий: как по-русски можно грамотнее всего "обозвать" Scope chains?
-------------------- Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму! |
|||
|
||||
| AKS |
|
|||
|
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
SelenIT, а я тут по-быстрому выскажусь, пока вы все спите ;)...
Как грамотнее - незнаю, а вот если "чисто" по-русски "обозвать", то могу вот так попробовать: Scope chain - ряд необходимых (видимых) объектов для исполняемой процедуры. |
|||
|
||||
| Zeroglif |
|
||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
Коротко фиг обзовёшь. Вот, например, как совсем не коротко, но зато метко описывается это дело у Харольда Абельсона и Джеральда Джея Сассмана (Структура и интерпретация компьютерных программ):
В том же русле, но уже на базе родного ECMAScript сжато я бы сказал так:
Если совсем закоротить для удобства:
Ещё короче не горазд. Это сообщение отредактировал(а) Zeroglif - 24.11.2006, 12:24 |
||||||||
|
|||||||||
| SelenIT |
|
|||
![]() баг форума ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3996 Регистрация: 17.10.2006 Где: Pale Blue Dot Репутация: 49 Всего: 401 |
AKS, Zeroglif, спасибо! Zeroglif, Ваше второе определение вообще блеск, лучше для понимания, наверное, сформулировать просто невозможно. ++
-------------------- Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму! |
|||
|
||||
| 12345c |
|
|||
![]() Круглый ![]() ![]() ![]() ![]() Профиль Группа: Vingrad developer Сообщений: 2018 Регистрация: 26.12.2005 Где: наша не пропадала ? Репутация: 57 Всего: 101 |
А исходное понятие closure лучше перевести (точнее, переназвать) как связывание или функция со связанными переменными.
Или ещё полнее, функция со связанными временными переменными (которые закончили своё существование). (При этом, если такого связывания нет, логичнее называть function функцией, как все делают, а не озадачивать народ глобальным утверждением, что в JS все функции - closures.) |
|||
|
||||
| Zeroglif |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
Наоборот. Если все переменные в функции (binding form) связаны (bound), то откуда тогда взяться замыканию. A вот ежели переменные не связаны своей функцией (free), то налицо оно самое, то есть, как минимум, функция должна быть со свободными переменными (опустим для простоты причуды с возможной eval-изацией строки в переменную)...
Имхо умирают и заново рождаются только локальные bindings, а те, что ищутся в лексическом окружении, они как бы создаются единожды в момент создания функции (будущего замыкания). Я про имена, не про значения. Чтобы всё-таки вычленить замыкание из ряда остальных функций, что определённо имеет смысл, я бы сказал, что это функция, которая: 1) пережила контекст исполнения, в котором она была создана; 2) имеет на борту свободные переменные; Два основных лейбла. Под переменными подразумевается понятно что. Это сообщение отредактировал(а) Zeroglif - 26.2.2007, 03:25 |
|||
|
||||
| 12345c |
|
|||
![]() Круглый ![]() ![]() ![]() ![]() Профиль Группа: Vingrad developer Сообщений: 2018 Регистрация: 26.12.2005 Где: наша не пропадала ? Репутация: 57 Всего: 101 |
Я имел в виду связывание с константой или значением, оставшимся после закрытия переменной. Т.е., в терминах "free", это возможно как раз с free vars. Которые можно описать как определённые вне функции, но временные, не глобальные. Не параметры своей функции и не создавшиеся в ней.
Что считать free variables - локальные и глобальные или только локальные? Как я понимаю, свойства closure проявляются только с локальными free. Тогда, если термин "связывание" занят под противоположным действием - связыванием с переменными, то как назвать связывание с константой после закрытия (удаления) переменной? |
|||
|
||||
| AKS |
|
|||
|
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
А может быть под термином closure нужно понимать совсем другое "явление природы"?
Может быть замыкание - это факт существования Activation/Variable объекта outer-функции в св-ве [[Scope]] inner-функции? А момент, когда на объект inner-функции не останется ссылок и Activation/Variable объект outer-функции станет доступным для удаления из памяти, можно назвать "концом жизни" замыкания. |
|||
|
||||
| Zeroglif |
|
||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
Понимаешь, в этом смысле что глобальные, что "временные" технически суть одно и то же, если смотреть на них из-под замыкания, которое видит только строгую цепочку объектов в [[Scope]].
Свободные переменные - это те, что не связаны функцией, сюда же попадают и те, что будут связаны глобальным объектом. Но с другой стороны, тогда нет т.н целостности объекта (замыкания), т.к. есть доступ извне, не знаю, правда, насколько это принципиально.
В том и дело, что переменная (имя) не удаляется, если живёт замыкание, то живёт и [[Scope]], живут и все свободные переменные (имена). Технически (не углубляясь в специфику) переменную связывает определённый Variable Object, который создаётся один раз и не умирает, т.к. он сильно нужен замыканию, ибо оно может обращаться к свободным переменным, пытаясь найти связь в одном из Variable Objects. p.s. вышеописанное - есть смесь чуждых и не чуждых javascript терминов Добавлено @ 13:12 Именно так, я уже писал раньше в этой ветке, что функциональная терминология немного притянута за уши (ну, и бог с ней). Важен не только факт существования Activation/Variable объектов, важна и множественность такого существования под каждое замыкание... |
||||||
|
|||||||
| 12345c |
|
||||
![]() Круглый ![]() ![]() ![]() ![]() Профиль Группа: Vingrad developer Сообщений: 2018 Регистрация: 26.12.2005 Где: наша не пропадала ? Репутация: 57 Всего: 101 |
Добавлено @ 13:50 Да, но глобальные переменные не вызывают ощущения "чудес", если читатель кодов не знает про особенности функций в JS. Стоит глобальная переменная и стоит, оставаясь такой. Интуитивно предполагается, что глобальная не должна становиться значением в момент определения функции, а локальная должна, потому что известно, что она прекратит существование. Создатели поступили наоборот: живут все как переменные, более того, временные продолжают жить. Ну зомби натуральные. |
||||
|
|||||
| Sardar |
|
|||
![]() Бегун ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6986 Регистрация: 19.4.2002 Где: Нидерланды, Groni ngen Репутация: 78 Всего: 317 |
Самое интересное, что легко узнать ещё на момент трансляции все переменные, используемые внутри closure. Отсюда действительно можно сделать "оптимизацию", физически разделив представление closure (функция связанная с лексическим контекстом) и функции (свободная функция).
12345c, в примере ты создал функции в переменных f2 и f3, не объявленных ранее, что привело к их автоматическому созданию в "самом верхнем контексте" a.k.a global. Это не очень хороший приём, т.к. засоряет global пространство имён. Добавлено @ 14:01 Знакомые с любым декларативным и"полу-декларативным" языком сразу всё поймут
Лучше всего понять это разделив переменную на значение и ссылку на значение. Объявляя переменную мы объявляем ссылку, присваивая значение мы изменяем ссылку на новое значение. Когда объект значение не имеет более ни одной ссылки, то он удаляется сборщиком мусора. Closure держит ссылки на все используемые значения, потому последние из памяти не удаляются, до тех пор, пока хоть кто нибудь ссылается на сам closure. Кстати, раз много-поточности в JS нет, то сборщик мусора реализуется элементарным подсчётом ссылок при каждой операции присвоения. -------------------- Опыт - сын ошибок трудных © А. С. Пушкин Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik Оценить мои качества можно тут. |
|||
|
||||
| Sardar |
|
||||
![]() Бегун ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6986 Регистрация: 19.4.2002 Где: Нидерланды, Groni ngen Репутация: 78 Всего: 317 |
Впрочем тут нужна поправка, в случае настоящего JS полностью отбросить ссылку на родительский контекст нельзя (тем самым освободив ссылки на все не используемые значения, а следовательно возможно освободив и сами значения). А всё потому что eval должен видеть все переменные, как и "обычный код":
В примере видим, что для cool необходим только а, а b необходима не явно (отследить транслятором нельзя). Если реализовать функции и контексты эффективно, то мы отбросим контекст test, тогда eval должен вывести NaN (автоматом созданная b в global будет undefined, последующая арифметика в NaN). Но бродилки "правильно" выполняют код, показывая что все родительские контексты реально сохраняются. Впрочем транслятор может быть на столько умён, что бы отслеживать появление eval и сохранять контексты тогда, когда это нужно. Но это не оправдывает излишней свободы eval, препятствующей эффективной по памяти реализации closure/функций. -------------------- Опыт - сын ошибок трудных © А. С. Пушкин Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik Оценить мои качества можно тут. |
||||
|
|||||
| 12345c |
|
||||||
![]() Круглый ![]() ![]() ![]() ![]() Профиль Группа: Vingrad developer Сообщений: 2018 Регистрация: 26.12.2005 Где: наша не пропадала ? Репутация: 57 Всего: 101 |
Этот пример ничего не показывает - до выхода из test перем. b сохраняется. Модифицируем:
Но весь сыр-бор не для этого, а чтобы проверить, как влияет eval на скорость операций. Допишем:
2 пары - потому что они имеют обыкновение останавливаться и спрашивать: работать ли дальше? Результаты говорят, что обе функции работают с одинаковой скоростью, наличие eval не усугубляет время выполнения (IE6, FF2). Опять же ,они не о многом говорят, если и происходит операция с памятью, то она может быть очень незаметной по времени. Как выявить различия? (Найти чёрную кошку в тёмной комнате.) Сделать конструктор временного массива вместо b? (Почти доказано, что в окружении он сохранится.) Устроить утечку памяти и измерять скорость её роста? Второе интересно. Если сделать функцию, отхватывающую по 1-10 К памяти на временные переменные, и создавать такие функции в цикле, то по скорости роста памяти можно сказать, образумливается когда-либо браузер с запоминанием окружения или нет, очищает ли он когда-либо память окружения. Это сообщение отредактировал(а) 12345c - 27.2.2007, 15:51 |
||||||
|
|||||||
| Sardar |
|
|||
![]() Бегун ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6986 Регистрация: 19.4.2002 Где: Нидерланды, Groni ngen Репутация: 78 Всего: 317 |
Нет, пример был что бы показать не возможность "отброса лишнего" при трансляции кода в байткод. Именно потому, что в JS код уже не является константой, а может модифицироваться из-за eval (тело функции другое из-за eval). Следовательно транслятор не способен определить какие ресурсы использует функция до этапа выполнения (изыскания на эту тему в фунегоидных языках). Другими словами реализуя интерпретатор JS я не смогу реализовать сохранение контекстов эффективно (в примере контекст от test будет висеть в памяти, удерживая ещё и b, хотя это не всегда нужно). Это к тому, что из-за такой казалось бы малой фичи как полная видимость переменных в eval делает код JS сложно транслируемым в бинарник. Просто мысли, к реальным браузерам не имеет отношения. Твой тест всего лишь показывает, что транслятор бродилки ипосльзоуемой в тесте возможно не так умён, что бы выявить closure без eval (возможно он вообще AST дерево эвалюирует), хотя такая фишка не очень сложна в реализации P.S. все мои мысли по поводу реализации JS из-за прошедшей лабы, написал язык Forthy, где объекты и closure реализованы почти как в JS. Eval не реализовывал (возможен парсинг и выполнение в рантайме, но видимы будут только используемые статическим кодом переменные), естественно контексты вышли фиксированными по размеру с линковкой по ссылке на этапе трансляции - читай шустро как в C'ях -------------------- Опыт - сын ошибок трудных © А. С. Пушкин Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik Оценить мои качества можно тут. |
|||
|
||||
| 12345c |
|
|||
![]() Круглый ![]() ![]() ![]() ![]() Профиль Группа: Vingrad developer Сообщений: 2018 Регистрация: 26.12.2005 Где: наша не пропадала ? Репутация: 57 Всего: 101 |
Это понятно, что мысли - для желающих написать свой язык. А ты свой переделывал в Пай-код? Или делался с расчётом на возможность трансляции до машинного?
Трансляция с eval видится возможной в виде гибрида - известный код транслируется, а в случае eval остаётся окружение с интерпретатором. И привязка машинных объектов к окружению (представление данных будет другим, поэтому надо иметь процедуру чтения машинного представления данных в интерпретаторе и наоборот). Но, возвращаясь к коду в браузерах, не очень приятное "открытие", что сохраняется весь контекст временных переменных в closure. Осталось выяснить, без eval он также будет сохранять весь контекст? |
|||
|
||||
| Sardar |
|
||||
![]() Бегун ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6986 Регистрация: 19.4.2002 Где: Нидерланды, Groni ngen Репутация: 78 Всего: 317 |
Да в байткод (p-код). Его можно развернуть до машинного, но по сути будет масса вызовов функций (или threaded код), опкоды высокоуровневы (стек ориентированны). На следующей лабе попробую реализовать интерпретатор с JIT'ом (за одно попробую регистр-ориентированный p-код, как в parrot)
А ничего совершенно не отличается, если только не применять через-чур агрессивные оптимизации, а их не просто реализовать. Контексты функций это фиксированные по размеру массивы (линковка по ссылке), объекты это хеш-таблицы (линковка в рантайме по имени), переменные это вероятней всего tagged ссылки и т.д. -------------------- Опыт - сын ошибок трудных © А. С. Пушкин Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik Оценить мои качества можно тут. |
||||
|
|||||
| 12345c |
|
||||||||
![]() Круглый ![]() ![]() ![]() ![]() Профиль Группа: Vingrad developer Сообщений: 2018 Регистрация: 26.12.2005 Где: наша не пропадала ? Репутация: 57 Всего: 101 |
Вношу коррективу: вначале я измерял время по последнему скрипту не совсем правильно - вызывал одну и ту же первую функцию с eval по недосмотру. Сейчас исправил код, уменьшил счётчик в 10 раз, чтобы не было остановов в FF, и вот что FF2 выдал:
"Самый быстрый в мире" Opera9.0 работает типично так:
Добавлено @ 16:18 (И при этом в предыдущем эксперименте показано, что b сохраняется в IE в любом случае.) |
||||||||
|
|||||||||
| Zeroglif |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
||||
|
||||
| 12345c |
|
|||
![]() Круглый ![]() ![]() ![]() ![]() Профиль Группа: Vingrad developer Сообщений: 2018 Регистрация: 26.12.2005 Где: наша не пропадала ? Репутация: 57 Всего: 101 |
Оригинально, но возвратимся к первому коду от Дата 26.2.2007, 22:40, с трассировкой, и получим (с window.eval()) в Опере-9, чтобы проверить, не теряется ли пространство имён:
|
|||
|
||||
| Zeroglif |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
!!!Отличная новость, напрямую связанная с замыканиями в IE.
MS на днях выпустила обновление, устраняющее известные многим утечки памяти. Цитирую, какую именно проблему пофиксили:
кросспостинг на xpoint-е Это сообщение отредактировал(а) Zeroglif - 22.6.2007, 21:07 |
|||
|
||||
![]()
|
| Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | JavaScript: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |