Также обратите внимание, что объединение
- концепция лексическая область действия (что, как мы считаем, является хорошей вещью для языка программирования, в отличие от динамическая область действия )
- с определениями функций (лямбда-выражениями), глубоко внедренными в код (такие определения можно также назвать «вложенными функциями», чтобы быть короткими)
может оказаться сложным делом, как с точки зрения языковой реализации, так и с точки зрения программиста. У этой сложной вещи есть даже специальное название: closure .
Как Википедия пишет :
Правильная реализация статического объема
на языках с первоклассным вложенным
функции не тривиальны, так как
требует каждого значения функции для переноса
с ним запись значений
переменные, от которых зависит (пара
функции и этой среды
называется замыканием ).
Это не только нетривиально для реализации в языке с глобальными и / или изменяемыми переменными (такими как C или Java; подумайте об обеспечении правильного доступа в момент оценки закрытия к изменяемому состоянию, которое находилось в области видимости на месте определения вложенной функции! Только одно: использованные объекты не должны были быть уничтожены и собраны мусором при оценке закрытия в будущем), но также концептуально это не тривиально для программисту подумать о том, как замыкание будет работать в сложной ситуации и какие (побочные) эффекты оно будет иметь точно (по той же причине: нужно подумать о взаимодействии замыкания со всем изменяемым состоянием, которое было в области видимости, когда вы определили замыкание, например: когда вы ссылаетесь внутри определения замыкания на внешнюю изменяемую переменную, которая находится в области действия, действительно ли вы хотите получить доступ к значению, которое переменная имела во время определения закрытие, т. е. вы хотите иметь только для чтения копию т переменная, или вы хотите полноценный доступ к изменяемому состоянию переменной в будущем во время оценки замыкания? ).
В чисто функциональных языках гораздо проще думать об определениях вложенных функций и их использовании, и поэтому наличие только лексической области видимости для них вообще не проблема. Но если ваш язык не функционален, это не так тривиально. (Я полагаю, что это одна из причин, почему долго обсуждали, как добавлять замыкания в Java: они не казались достаточно тривиальными для понимания программистом, хотя они просто основывались на хорошей концепции лексического контекста .)
Думать о вложенных функциях в не чисто функциональных языках проще с динамической областью (хотя динамическая область не очень приятна: вы получаете меньше проверок во время компиляции и гарантии правильного поведения вашей программы с динамической областью действия).
Так что я думаю, что преимущество наличия динамического определения объема на языке также может заключаться в возможности программировать некоторые вещи простым способом, если кто-то захочет и осмелится сделать это , учитывая все опасности динамического Объем.
Примечания
Относительно длинной истории (нет) замыканий в Java (и того, что программистам не понравилась концепция) - http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg04030.html:
Дата: четверг, 14 августа 2003 г. 08:05:44 -0700
От: Майкл Ванье
Тема: Re: привязки и назначения (было: Re: продолжения)
Дата: четверг, 14 августа 2003 г. 10:45:34 -0400
От: "Дэвид Б. Такер"
Я представляю, хотя у меня нет статистических данных, что
Требование объявления локальных переменных, чтобы быть окончательным, чтобы
ссылаться на них внутри анонимных внутренних классов (замыканий) почти
полностью неизвестен и не используется на практике.
Из любопытства кто-нибудь знает, почему Java допускает только финал?
переменныессылаться из анонимных классов?
Dave
<cynic>Otherwise you'd have the equivalent of true closures,
and if you had that java would be a
*really* powerful and useful language, so they obviously couldn't do that.
</cynic>
Собственно, реализация прототипа
did позволял ссылаться на не финальные переменные из внутренних классов.
Был протест от пользователей ,
жаловаться что не хотели
этот! Причина была интересной: в
Для того, чтобы поддерживать такие переменные, это
нужно было их куча-выделить,
и (в то время, по крайней мере)
средний Java-программист был еще
довольно капризный о распределении кучи
и сборка мусора и все такое.
Они не одобряли язык
выполнение выделения кучи "под
стол ", когда не было ни одного случая
"новое" ключевое слово в поле зрения.
Итак, в первые дни - по-видимому - «третий» подход (в отличие от двух, о которых я упоминал в моем тексте выше) должен был быть принят в Java: ни «копии только для чтения», ни реальный доступ во время оценки к включающему (во время определения замыкания) изменчивому состоянию, но скорее изменчивым копиям состояния (по крайней мере, я так понимаю процитированный отрывок, или нет, он говорит о выделять кучу только ссылок? .. Тогда это второй вариант. Хорошо. Третий вариант действительно не кажется мне разумным.). Не знаю, как они реализуют замыкания в настоящее время в Java, я не следил за новинками о Java.