Функциональное программирование |
Функциональное программирование всегда привлекало меня в противопоставлении к императивному.
Я очень часто обсуждаю различные аспекты функционального программирования на различных ветках на Базарной площади.
Но хотелось бы собрать всех заинтересованный этой темой в одной ветке.
Я думаю что настало время открыть такую тему. И вот почему.
Исторически функциональное программирование появилось практически вместе с императивным.
Вторым языком после фортрана был лисп.
Но увы, функциональное программирование надолго было уделом исследовательских институтов или специализированных приложений (Искусственный Интеллект)
Конечно не надо считать весь мир дураками из за того что развитие пошло по пути языков Алгол семейства.
Для этого были вполне обьективные причины. Функциональные языки слишком близки к человеку и слишком далеки от машины.
Они сьедают в десятки раз больше рессурсов чем императивные языки.
Вспомните претензии, предявляемые к java - первому императивному языку с виртуальной машиной и сборщиком мусора, толкаемому большими корпорациями в mainstream.
Жутко тормозит, и жрет всю память какая есть. А ведь функциональные языки (далее ФЯ) все без иключения имеют сборщик мусора, виртуальную машину.
Многие из них (семейство лисп) еще и динамические, что только усугубляет положение.
Вполне естественно что появившись более полусотни лет назад они надолго опередилли свое время.
Для широкого распространения ФЯ нужны гигабайты дешевой памяти и гигагерцы дешевых процессоров.
Прошло более 50 лет, прежде чем такие требования к железу стали реальностью.
Это время наступило. СЕЙЧАС.
Добро пожаловать в новую эру программирования.
Jack Of Shadows
Всего в теме 5502 сообщения
Добавить свое сообщение
Отслеживать это обсуждение
- Средства разработки. Языки программирования.
- Delphi 4 or Delphi 5
- Что приобрести в качестве средства разработки?
- Delphi6
- Delphi vs PowerBuilder
- Сравнение компиляторов
- Вот и вышла Delphi 7... Вы рады?
№ 542 29-07-2006 15:43 | |
Ответ на »сообщение 539« (hugi)
___________________________
Хотели посмотреть код аналогичный по функциональности Вашему макросу?
Не аналогичный по функциональности, а аналогичный по записи.
Аналогичный по функциональности код можно написать самыми разновобразными способами на самых разнообразных языках. Единственное необходимое условие при этом - Turing complete language.
Но вы же сами не согласитесь с тем что VB и дельфи аналогичены, потому что любую функциональность сделанную на дельфи, можно сделать и на VB
Наверное важно не только <b>что можно</b> но и <b>как можно</b>
Приведите код аналогичный (или хотя бы похожий) по записи.
А если не можете то и не надо говорить "почти такой же код" (Это к Сергею Перовскому) Потому что только слепой не увидит что код сильно отличается, хотя да, функциональность одна и та же.
№ 541 29-07-2006 15:04 | |
Ответ на »сообщение 540« (Jack Of Shadows)
___________________________
Жаль нельзя править свои сообщения.
Перепутал теги Code и Quote
(with-db-connection sirusdb
(dolist (row ((select [d.orderno], [d.dist_id], [oc.custcode] :as ord_custcode, [bc.custcode] :as bill_custcode
:from [distribution d] :inner-join [customer oc] :on [d.cust_id] = [oc.acctno]
:inner-join [customer bc] :on [d.billfirmid] = [bc.acctno]
:where [orderno] = order-no
:order-by 1))
(assert ((make-instance 'dist-locat :wo (first row)
:dist-locat-id (second row)
:ord-cust-code (third row)
:bill-cust-code (fourth row)))))))
№ 540 29-07-2006 15:02 | |
Ответ на »сообщение 539« (hugi)
___________________________
Спасибо! :))
Прекрасный пример невероятной громоздкости сишарпа и java.
Вот пример использования with-db-connection в моем коде:
(with-db-connection sirusdb
(dolist (row ((select [d.orderno], [d.dist_id], [oc.custcode] :as ord_custcode, [bc.custcode] :as bill_custcode
:from [distribution d] :inner-join [customer oc] :on [d.cust_id] = [oc.acctno]
:inner-join [customer bc] :on [d.billfirmid] = [bc.acctno]
:where [orderno] = order-no
:order-by 1))
(assert ((make-instance 'dist-locat :wo (first row)
:dist-locat-id (second row)
:ord-cust-code (third row)
:bill-cust-code (fourth row)))))))
Вот он же на paste: http://paste.lisp.org/display/23349
Почувствуйте разницу как говорится :))
Кстати, в этом же примере можно видеть как я использую встроенный sql, который дает мне проверку валидности на этапе компиляции.
В данном случае dolist это цикл, который гонит по возвращенному списку записей из таблицы, и создает обьекты в базе знаний (это кусок кода из сервера правил)
№ 539 29-07-2006 13:48 | |
Ответ на »сообщение 535« (Jack Of Shadows)
___________________________
Простите, но
with-db-connection my-conn
begin
...
end
гораздо более читабельнее и понятнее нежели
WithDBConnection(My12345LocalFunction(a, b, c));
Простите, а
with-db-connection my-conn
begin
...
end
это Лисп?
Хотели посмотреть код аналогичный по функциональности Вашему макросу? Пожалуйста: http://paste.lisp.org/display/23345 Правда, код на C#, но я думаю, это не критично. То же самое можно сделать на Delphi, применив не делегат, а локальную процедуру, которая также может "общаться" с вызывающей через локальные параметры.
№ 538 29-07-2006 11:37 | |
Ответ на »сообщение 536« (Сергей Перовский)
___________________________
Кстати, вы затронули интересный вопрос - роль синтаксиса, операторов в функциональном программировании.
Роль эта не маленькая.
Функциональное программирование это конечно фундаментальное направление.
Но просто набор функций не может заменить человеку синтаксис, не может отменить необходимость во множетсве специализированных языков.
Возьмем для примера хаскель и list comprehensions.
Хаскель это чистый ФЯ, не всеядныяй как лисп, не легко морфирующий синтаксис как лисп.
С точки зрения чистого функционального подхода list comprehensions не дают ничего что невозможно было бы достичь при помощи использования функций для работы со списками.
Это просто синтаксический сахар, спобоб короткой записи часто встречающихся операций со списками.
Что то типа 5 + 4 вместо Add(5,4)
При этом не особенно то много и экономит места.
Однако создатели хаскель пошли на изменение языка и встроили в него новые конструкции, хотя еще раз повторяю эти конструкции не дают абсолютно ничего чего нельзя было бы сделать при помощи уже имевшихся функций.
Так что как видите, DSL (встроенные языки для специфических задач) а также введение новых конструкций в язык, не противоречит ФП и является для функциональных программистов важным и необходимым инструментом.
В этом плане у лиспа конечно колоссальное преимущество даже по сравнению с хаскелем.
Надеюсь вы не подумаете что я призываю заменить одно другим.
ФП - базис, DSL - важный и нужный инструмент, который одинаково хорошо работает как на функциональной так и на императивной базе.
Макросы - один из способов создания DSL, лучше всего реализованный на сегодняшний день в лиспе.
Но есть и другие подходы для создания DSL.
Это и визуальная среда (delphi), и препроцесооры (AspecJ), и software factories, которые анонсируются дл следующей версии dotnet.
Ни один из этих подходов не заменяет базис, на котором они строятся.
№ 537 29-07-2006 11:15 | |
Ответ на »сообщение 536« (Сергей Перовский)
___________________________
For the sake of it - yes.
И потом это был не единственный аргумент.
Вы так и не привели ваш код.
И ваша "почти такой же как у вас" зависла в пустоте.
И ваше обвинение в нечитабельности кода с макросами тоже.
Я говорю о том, что вы приводите неверные утверждения, а потом, когда они развенчаны, цепляетесь за вырванные из контекста фразы.
Давайте вернемся к вашим утверждениям.
У вас есть что либо возразить по поводу читабельности, удобства и простоты в сравнении вашего подхода и подхода с макросами ?
№ 536 29-07-2006 10:40 | |
Ответ на »сообщение 535« (Jack Of Shadows)
___________________________
>>>Вам приходится писать его отдельно в виде функции, а потом передавать функцию.
Ожидал именно этого аргумента :)
Необходимость оформить часть кода как функцию - большой грех, особенно с точки зрения функционального программирования :)
№ 535 29-07-2006 10:14 | |
Ответ на »сообщение 534« (Сергей Перовский)
___________________________
Ну а я использую в Дельфи процедуру, параметрами которой являются база, которую надо открыть и процедура, которую надо над ней выполнить. Возвращает код завершения.
Смешно, что ее код Вы почти полностью привели.
Ну это неправда. Ваш код в принципе не может быть похож на тот что я привел.
Вы не можете передавать кусок кода.
Вам приходится писать его отдельно в виде функции, а потом передавать функцию.
Это во первых.
Во вторых вы сильно ограничены сигнатурой передаваемой функции. Ваша функция возвращает код завершения.
А это значит что всю полезную работу надо запихивать в нее.
А как быть со случаями кодга надо просто вернуть из БД список, скажем для заполнения выпадающего списка ?
Или не возвращать ничего а записать что то в бд. Причем что что находящееся в локальных переменных или локальных обьектах ? Ведь сигнатура то функции одна. Вы ограничены набором передаваемых параметров и их типами. Или вы все в глобальных держите ? чтобы ничего не передавать ?
В случае же с макросом вы просто передаете кусок кода, не надо никаких параметов, все локальные переменные доступны, не надо никаких возвращаемых переменных. все результаты доступны.
При этом не нарушается инкапсуляция. Локальное остается локальным.
Повторяю еще раз приведите код использования вашей функции (хотя я прекрасно представляю как он выглядит)
и мы с вами убедимся в истинности вашего утверждения что он "почти такой же" как и макрос который я привел.
Но простота трансляции и простота понимания и использования это разные вещи.
Простите, но
with-db-connection my-conn
begin
...
end
гораздо более читабельнее и понятнее нежели
WithDBConnection(My12345LocalFunction(a, b, c));
Это сколько же вам таких локальных функций надо создать с огромным количеством по возможности говорящих и понятных имен :))
Да еще все функции где то, вполне может быть даже не рядом с блоком, хотя работа там может быть мелкая.
Вы это называете "простота понимания" ?
Необходимость каждый селкий кусок кода, в котором нужно что то делать с БД, оформлять в виде ОДНОРАЗОВОЙ функции, то есть кодаЮ который вы нигде больше не будете использовать, вы называете "простотой использования" ? И это в сравнении с кодом который я привел ?
Воистину у людей совершенно разные представления о простоте, читабельности и удобстве :))
№ 534 29-07-2006 07:09 | |
Ответ на »сообщение 523« (Jack Of Shadows)
___________________________
Любой, работавший с Базами данных, знает, что нужно совершать некую последовательность действий, независимо от того что вы делаете.
1. Открыть соединение.
2. Выполнить какую то работу.
3. Закрыть соединение.
Ну а я использую в Дельфи процедуру, параметрами которой являются база, которую надо открыть и процедура, которую надо над ней выполнить. Возвращает код завершения.
Смешно, что ее код Вы почти полностью привели.
Может поискать более яркий пример?
Мы тут все очень часто этим грешим: то что я могу эффективнее решать некоторые задачи с помощью инструмента A, чем B зачастую говорит только о моем плохом знании B, а не преимуществах инструмента A.
Основным преимуществом лиспа является простота синтаксического разбора. Но простота трансляции и простота понимания и использования это разные вещи.
№ 533 28-07-2006 15:33 | |
Ответ на »сообщение 531« (Артем)
___________________________
Ну, неужели, мир перевернется, если я смогу не писать где-то блоки try –except?
Ну неужели мир перевернется если где то я смогу не писать destroy и Free ? :))
Сколько раз мы это слышали ?
За деревьями не видите леса ?
Добавить свое сообщение
Отслеживать это обсуждение
Дополнительная навигация: |
|