вторник, 21 июня 2011 г.

[prog.flame] Понравилось высказывание Бертранда Мейера

Цитата из свежей записи в блоге Бертранда Мейера:

Functional programming languages have also offered interesting idioms for concurrency, taking advantage of the non-imperative nature of functional programming. Advocacy papers have argued for Haskell [10] and Erlang [11] in this role. But should the world renounce other advances of modern software engineering, in particular object-oriented programming, for the sake of these mechanisms? Few people are prepared to take that step, and (as I have discussed in a detailed article [12]) the advantages of functional programming are counter-balanced by the superiority of the object-oriented model in its support for the modular construction of realistic systems.

Что, в моем переводе звучит как:

Функциональные языки программирования так же предлагают интересные идиомы для конкурентности, получающие преимущества из неимперативной природы функционального программирования. Пропагандистские публикации указывают на Haskell [10] и Erlang [11]. Но должен ли мир оказаться от других преимуществ современной инженерии программного обеспечения, объектно-ориентированного программирования в частности, ради этих механизмов? Некоторые приготовились сделать этот шаг, но (как я более подробно рассматривал в статье [12]) преимущества функционального программирования перевешиваются превосходством объектно-ориентированной модели в поддержке модульного конструирования реалистичных систем.

Вот упомянутые в цитате ссылки:

[10] Simon Peyton-Jones: Beautiful Concurrency, in Beautiful Code, ed. Greg Wilson, O’Reilly, 2007, also available online.

[11] Joe Armstrong: Erland, in Communications of the ACM, vol. 53, no. 9, September 2010, pages 68-75.

[12] Bertrand Meyer: Software Architecture: Functional vs. Object-Oriented Design, in Beautiful Architecture, eds. Diomidis Spinellis and Georgios Gousios, O’Reilly, 2009, pages 315-348, available online.

Понравилась цитата потому, что как и Б.Мейер, я являюсь приверженцем объектного подхода (пусть не таким продвинутым) и так же имею сильные сомнения на счет преимуществ функционального подхода. Поэтому отрадно, когда аналогичные сомнения высказывает намного более сведущий в computer science специалист, чем я.

PS. В заключение дам ссылку на свою старую заметку: Об интуитивности императивного и функционального программирования.

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

  1. А чем функциональная парадигма хуже в "поддержке модульного конструирования" ?

    ОтветитьУдалить
  2. @Left:

    К сожалению, статью Мейера я еще не читал. Поэтому не могу (пока) сказать, что имел в виду Мейер.

    На мой взгляд, модульность, которая есть в Ada, Modula-2, Turbo Pascal, а так же похожая на нее модульность в C++/Java/C#/Eiffel направлена на то, чтобы скрывать состояние модуля/объекта, предоставляя наружу только интерфейсы для управления состоянием.

    Тогда как в ФП если какой-то сущности нужно сохранять свое состояние между обращениями к ней, то здесь состояние выставляется наружу. И забота о ее хранении перекладывается на пользователя сущности.

    ОтветитьУдалить
  3. > Тогда как в ФП если какой-то сущности нужно сохранять свое состояние между обращениями к ней, то здесь состояние выставляется наружу. И забота о ее хранении перекладывается на пользователя сущности.

    Вот этого не понял
    Ну возьмём к примеру монаду IO в Haskell - что-то я не вижу где тут внутреннее состояние торчит кишками к юзеру.

    ОтветитьУдалить
  4. @Left:

    Если уж речь зашла о монадах, то где здесь ФП?

    ОтветитьУдалить
  5. > Если уж речь зашла о монадах, то где здесь ФП?

    Озадачен вопросом. А где ООП в полиформизме или инкапсуляции?

    ОтветитьУдалить
  6. @Left:

    Прошу прощения за паузу перед ответом.

    >Озадачен вопросом.

    Я вот о чем: когда кто-то начинает использовать чужой IO с непонятно какими побочными эффектами внутри, то чем это оличается от использования какого-нибудь java.lang.stdout?

    Когда у вас есть чужая библиотека в чисто функциональном стиле -- т.е. без побочных эффектов, с явным протаскиванием состояния и пр. -- тогда вы можете автоматически получить бенефиты исходя из природы ФП. Безопасное использование в многопоточном приложении. Или, скажем, автоматическое распараллеливание (если компилятор достаточно умный).

    Но когда есть непрозрачная ни для кого IO, то что из этого есть в вашем распоряжении? Какую цену, например, придется платить за ее использование в многопоточных приложениях?

    На мой дилетанский взгляд здесь мы оказываемся в том же самом положении, что и в насквозь императивных языках.

    ОтветитьУдалить
  7. Приведу, на мой взгляд, нормальный пример проблем с модульностью.

    Предположим, что у нас есть библиотека regex_match для поиска в тексте с использованием regex-ов. В этой библиотеке есть функция:

    match :: String -> Regex -> MatchParams -> MatchResult

    Это чистая функция, без побочных эффектов. И, в принципе, это логично.

    Однако, со временем вы захотели модифицировать ее. Например, реализовать промежуточные дампы в файлы для последующей отладки. Или, что более вероятно, выяснилось, что в вашем приложении чаще всего происходит поиск одних и тех же выражений в одних и тех же строках. Поэтому очень выгодно было бы сделать мемоизацию (кэширование результатов). Соответственно, появляются побочные эффекты.

    В ООП прототип match не изменился бы никак. Внешний интерфейс от смены реализации не зависит. А вот в ФП прототип match пришлось бы поменять:

    match :: String -> Regex -> MatchParams -> IO MatchResult

    И что после этого делать с местами использования match в коде? Вносить соответствующие правки и, опять же, протягивать невесть откуда взявшийся IO вверх?

    ОтветитьУдалить
  8. В не ленивых функциональных языках с инкапсуляцией типов в модулях никаких проблем нет. В том же OCaml типичный прием такой (псевдокод)

    Module mytype

    В сигнатуре модуля

    type t

    В реализации модуля уже полное описание

    type t = A | B of int | ....

    Снаружи виден только Mytype.t и функции с ним работающие, внутри мы можем менять Mytype.t как угодно.

    ОтветитьУдалить
  9. @Rustam:

    Так ведь применительно к конкурентности, о которой изначально говорил Мейер такие модули OCaml-а вряд ли дают ему какие-то преимущества перед Java или C#. Правильно?

    ОтветитьУдалить
  10. @Евгений

    Модульность на конкурентность никак ни влияет. На это влияет только чистота.

    При этом я не вижу никакой большей модульности у ОО языков по сравнению с функциональными. Да в ОО каждый объект модуль, но в ФЯ каждая функция (особенно с замыканием) тоже модуль.

    ОтветитьУдалить
  11. @Rustam

    >На это влияет только чистота.

    Это если чистота не фиксируются системой типов, что отражается затем на декларации содержимого модуля.

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

    Может это еще от ФЯ зависит. OCaml, имхо, от Hasjell-я с Erlang-ом очень сильно отличается.

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