вторник, 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 комментариев:

Left комментирует...

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

eao197 комментирует...

@Left:

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

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

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

Left комментирует...

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

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

eao197 комментирует...

@Left:

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

Left комментирует...

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

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

eao197 комментирует...

@Left:

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

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

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

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

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

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

eao197 комментирует...

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

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

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

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

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

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

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

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

Rustam комментирует...

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

Module mytype

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

type t

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

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

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

eao197 комментирует...

@Rustam:

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

Rustam комментирует...

@Евгений

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

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

eao197 комментирует...

@Rustam

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

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

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

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