Цитата из свежей записи в блоге Бертранда Мейера:
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 комментариев:
А чем функциональная парадигма хуже в "поддержке модульного конструирования" ?
@Left:
К сожалению, статью Мейера я еще не читал. Поэтому не могу (пока) сказать, что имел в виду Мейер.
На мой взгляд, модульность, которая есть в Ada, Modula-2, Turbo Pascal, а так же похожая на нее модульность в C++/Java/C#/Eiffel направлена на то, чтобы скрывать состояние модуля/объекта, предоставляя наружу только интерфейсы для управления состоянием.
Тогда как в ФП если какой-то сущности нужно сохранять свое состояние между обращениями к ней, то здесь состояние выставляется наружу. И забота о ее хранении перекладывается на пользователя сущности.
> Тогда как в ФП если какой-то сущности нужно сохранять свое состояние между обращениями к ней, то здесь состояние выставляется наружу. И забота о ее хранении перекладывается на пользователя сущности.
Вот этого не понял
Ну возьмём к примеру монаду IO в Haskell - что-то я не вижу где тут внутреннее состояние торчит кишками к юзеру.
@Left:
Если уж речь зашла о монадах, то где здесь ФП?
> Если уж речь зашла о монадах, то где здесь ФП?
Озадачен вопросом. А где ООП в полиформизме или инкапсуляции?
@Left:
Прошу прощения за паузу перед ответом.
>Озадачен вопросом.
Я вот о чем: когда кто-то начинает использовать чужой IO с непонятно какими побочными эффектами внутри, то чем это оличается от использования какого-нибудь java.lang.stdout?
Когда у вас есть чужая библиотека в чисто функциональном стиле -- т.е. без побочных эффектов, с явным протаскиванием состояния и пр. -- тогда вы можете автоматически получить бенефиты исходя из природы ФП. Безопасное использование в многопоточном приложении. Или, скажем, автоматическое распараллеливание (если компилятор достаточно умный).
Но когда есть непрозрачная ни для кого IO, то что из этого есть в вашем распоряжении? Какую цену, например, придется платить за ее использование в многопоточных приложениях?
На мой дилетанский взгляд здесь мы оказываемся в том же самом положении, что и в насквозь императивных языках.
Приведу, на мой взгляд, нормальный пример проблем с модульностью.
Предположим, что у нас есть библиотека regex_match для поиска в тексте с использованием regex-ов. В этой библиотеке есть функция:
match :: String -> Regex -> MatchParams -> MatchResult
Это чистая функция, без побочных эффектов. И, в принципе, это логично.
Однако, со временем вы захотели модифицировать ее. Например, реализовать промежуточные дампы в файлы для последующей отладки. Или, что более вероятно, выяснилось, что в вашем приложении чаще всего происходит поиск одних и тех же выражений в одних и тех же строках. Поэтому очень выгодно было бы сделать мемоизацию (кэширование результатов). Соответственно, появляются побочные эффекты.
В ООП прототип match не изменился бы никак. Внешний интерфейс от смены реализации не зависит. А вот в ФП прототип match пришлось бы поменять:
match :: String -> Regex -> MatchParams -> IO MatchResult
И что после этого делать с местами использования match в коде? Вносить соответствующие правки и, опять же, протягивать невесть откуда взявшийся IO вверх?
В не ленивых функциональных языках с инкапсуляцией типов в модулях никаких проблем нет. В том же OCaml типичный прием такой (псевдокод)
Module mytype
В сигнатуре модуля
type t
В реализации модуля уже полное описание
type t = A | B of int | ....
Снаружи виден только Mytype.t и функции с ним работающие, внутри мы можем менять Mytype.t как угодно.
@Rustam:
Так ведь применительно к конкурентности, о которой изначально говорил Мейер такие модули OCaml-а вряд ли дают ему какие-то преимущества перед Java или C#. Правильно?
@Евгений
Модульность на конкурентность никак ни влияет. На это влияет только чистота.
При этом я не вижу никакой большей модульности у ОО языков по сравнению с функциональными. Да в ОО каждый объект модуль, но в ФЯ каждая функция (особенно с замыканием) тоже модуль.
@Rustam
>На это влияет только чистота.
Это если чистота не фиксируются системой типов, что отражается затем на декларации содержимого модуля.
>При этом я не вижу никакой большей модульности у ОО языков по сравнению с функциональными.
Может это еще от ФЯ зависит. OCaml, имхо, от Hasjell-я с Erlang-ом очень сильно отличается.
Отправить комментарий