среда, 23 декабря 2009 г.

Динамическая область видимости

Прочитал в последнем номере журнала "Практика функционального программирования" в статье про "Элементы функциональных языков" буквально следующее:
В языке LISP присутствовали замыкания с динамической областью видимости, нарушавшие законы лямбда-исчисления и, вообще говоря, неудобные в использовании. Emacs LISP— практически единственный используемый на практике современный язык программирования, где используется динамическая область видимости.
Т.е. тут два посыла:
  • Динамическое область видимости неудобна
  • Динамическая область видимости осталась только в ELisp
Теперь вот сижу, пытаюсь найти мотивацию для дальнейшего прочтения, это же надо, так высказаться об одном из ключевых и наиболее удобных свойств Common Lisp: динамические переменные это потрясающе удобно и поэтому используются в коде на Common Lisp чрезвычайно широко.

14 комментариев:

  1. Я вот в цитате вижу куда более неприятные посылы:
    * LISP *был* (да сплыл, видимо)
    * Common Lisp не применяется на практике

    Откуда такие мысли у авторов, правда, банальная неграмотность ли это или умышленное искажение фактов с целью представить некоторые ф.я. современнее и практичнее лиспов - я не подозреваю.

    ОтветитьУдалить
  2. @love5an
    Не, ну применяется или нет, это всегда такой вопрос вонючий, часто сводится к процентам, а поскольку они неизвестны, то субъективным ощущениям, а вопрос о практичности вообще сплошь субъективный, но в статье, где так много ссылок, нельзя же говорить откровенную неправду, иначе ценность этих ссылок сразу ставиться под сомнение.

    Да и вообще, кажется автор не настолько разбирается в теме, как хочет казаться. Скажем, в главе про "сопоставление с образцом" нет ни слова про унификацию, что вызывает у меня глубокое недоумение...

    ОтветитьУдалить
  3. LISP (который именно большими буквами) -- это тот язык, который был реализован в интерпретаторе, написанном студентами Маккарти. И то ли в нем, то ли в языке, была динамическая область видимости (потому что реализация на компьютере *очень* простая). В общем, как вы тут разглядели CL, мне непонятно.

    2 love5an
    > Я вот в цитате вижу куда более неприятные посылы:
    > * LISP *был* (да сплыл, видимо)

    Вот именно, сплыл.

    > * Common Lisp не применяется на практике

    Лол, как Вы это вывели?

    ОтветитьУдалить
  4. У Маккарти это LISP 1.5. Просто Lisp это как бы семейство языков.
    Вывод о CL следует из

    >Emacs LISP— практически единственный используемый на практике современный язык программирования, где используется динамическая область видимости.

    и из собственно пассажа о динамической области видимости.

    конкретнее:
    "динамическая область видимости - несовременно"
    и
    "Emacs Lisp - единственный из достойных упоминания языков с динамической областью видимости, используемый на практике"
    ==>
    "Остальные лиспы устарели и не используются на практике"

    ОтветитьУдалить
  5. 2 love5an
    > У Маккарти это LISP 1.5. Просто Lisp это как бы семейство языков.

    Значит, в статье неточность, только и всего.

    > "динамическая область видимости - несовременно"

    Хм, почитайте тот же PLAI, там описывается, почему динамическая область видимости по-умолчанию -- это не просто несовременно, но еще и нехорошо, ибо разрушает процедурную абстракцию.

    > "Emacs Lisp - единственный из достойных упоминания языков с динамической областью видимости, используемый на практике"

    В Emacs Lisp динамическая область видимости принята по-умолчанию (статическую, AFAIK, нужно реализовывать самому). В CL тоже?

    ОтветитьУдалить
  6. Не понимаю, что значит "по умолчанию".

    "Глобальные" переменные в CL(объявляемые через defvar и defparameter) - динамические.
    progv создает динамические биндинги
    let создает лексические биндинги если имя уже не обозначено как имя динамической переменной

    ОтветитьУдалить
  7. @Artyom Shalkhakov
    http://lisper.ru/articles/cl-vars - вот хорошая (и небольшая) статья на тему лексических и динамических переменных

    ОтветитьУдалить
  8. А какая разница между "сравнением с образцом" и унификацией в данном случае?

    ОтветитьУдалить
  9. @antares0
    Унификация более общее понятие, с более широкой областью применения, например, я использую унификацию в cl-routes для сопоставления url коду обработчика.

    Для CL есть, например, cl-unification, которая, в том числе, предоставляет инструменты для "pattern matching": http://common-lisp.net/project/cl-unification/control-flow.html

    С другой стороны, автор позиционирует "сравнение с образцом" как достижения системы типов, но, если говорить о "pattern matching" как о частном случае применения унификации, то подобное утверждение становится, очевидно, сомнительным.

    ОтветитьУдалить
  10. В чем эта большая широта применения проявляется?
    cl-unification видел, cl-routes тоже смотел но более бегло.
    Пример или код в котором это разница была бы видна отчетливо?
    Просто я не могу могу сходу назвать другого применения для унификации чем это самое сравнение с образцом. Но может я глубоко заблуждаюсь.

    ОтветитьУдалить
  11. @antares0
    Унификация родилась вовсе не для "pattern matching", а как один из базовых элементов систем логического вывода.

    ОтветитьУдалить
  12. Поэтому в первом своем комментарии я и писал "в данном случае". Все таки pattern matching обычно не связан с системами лог.вывода, если не считать ,конечно, рег. выражения такими системами.
    С другой стороны и в помянутых системах унификацация используется для операций (if (eq объект паттерн) то иначе).
    Или я опять что-то упускаю?

    ОтветитьУдалить
  13. @antares0
    > используется для операций
    > (if (eq объект паттерн) то иначе)

    Нет. В cl-routes, во-первых, строится "унифицирующее дерево", которое позволяет вести поиск в дереве, а не линейном списке (это критично для сайтов, имеющих сотни, или даже тысячи маршрутов). Во-вторых, унификация ведётся в обе стороны, т.е. оба выражения содержат неизвестные, что позволило весьма существенно упростить решение, при этом, суть даже не сколько в проверке на соответствие образцу (хотя это, конечно, очень важно), сколько в "двухстороннем" извлечении значений параметров.

    ОтветитьУдалить
  14. В Perl тоже есть объявления с динамическим scope, почему-то об этом все забыли. Правда лучше их там не использовать...

    Насчет же CL - они здесь настолько удобны (и имеют абсолютно надежное и предсказуемое поведение во всех реализациях CL (в отличии от Perl)) что конечно, нужно лишь осознанно сдерживать себя от чересчур большого нагружения логики приложения на них. Т.е. просто задавать себе вопрос "а я по-прежнему все контролирую (через REPL, тесты)?".

    ОтветитьУдалить