Автор Тема: Функции против процедур  (Прочитано 85631 раз)

igor

  • Sr. Member
  • ****
  • Сообщений: 438
    • Просмотр профиля
Re:Функции против процедур
« Ответ #60 : Февраль 28, 2011, 07:59:14 pm »
Цитата: Geniepro
Ну, собственно, в Хаскелле контроль за побочными эффектами возложен именно на систему типов.
...
Цитата: DIzer
Ладно, господа давайте , подождем реакции Игоря-мне лично не очень понятно что он имел ввиду...  на эту мысль наводят его определения....функций и процедур.
Может быть я разочарую публику, но честно должен признаться что не компетентен в Хаскеле. Так что здесь пока без комментариев.

Цитата: DIzer
Как я понял речь идет именно о разделении чистый -грязный (об устранении побочного эффекта речь не идет). Но зачем Ф и П  -может хватит модификатора PURE в заголовке? Это по внешнему виду. Возникает вопрос как обеспечить это ?
Введение модификатора сулит, казалось бы, дополнительную гибкость: хочешь - объявляй чистую функцию, а хочешь - грязную. Но здесь не всё так просто. По большому счёту нужно чтобы не только функции были чистыми, но и выражения. У выражения и у функции схожая цель: вычислить значение. Хотя средства, ну и нотация, могут быть разные.
Представьте себе. Сегодня вот эта функция была у нас чистая, а завтра мы решили её сделать грязной (убрали модификатор PURE и добавили в неё вывод в лог). Но при этом все выражения в которых она была использована в качестве операнда, мгновенно стали грязными. Теперь нам надо отыскать все 120 этих выражений, разбросанных по 30 модулям, и в каждом из этих случаев решить критично это изменение или нет.

Цитата: DIzer
Простейший гемор - вы определяете набор совершенно чистых функций = которые прекрасно компилируются = но делаете из них DLL - и компилятор перестает считать их таковыми (Хотя они ими ОСТАЛИСЬ)  Wink
А вот тут стоп! Использование DLL - это платформозависимый вопрос. Правила платформы легко могут вступить в противоречие с правилами языка, который мы используем. И вообще, все внешние сущности (например, из DLL) не обязаны подчиняться правилам нашего языка. Уповать на то, что вот эта DLL была написана на нашем языке, в общем случае не приходится.

Цитата: vlad
Данные в немаленьких системах не лежат настолько открыто, чтобы функции могли "прочитать" все что нужно. Данные инкапсулированы и скрыты за абстракциями. Т.е., разделение на процедуры/функции должно распространятся и на методы (связанные процедуры/функции).
Мне кажется более правильным подход к инкапсуляции, принятый в Оберонах, нежели в классическом ООП. В Оберонах любые поля и методы любого объекта, объявленного в каком-либо модуле, доступны из любой точки этого модуля. Так что, исходный посыл, что "данные инкапсулированы и скрыты за абстракциями" получается как бы не верен.
Насчёт того, что методы также должны разделяться на процедуры/функции, согласен с Вами.
Кстати, здесь встаёт интересный вопрос, а разрешить ли методам-функциям (чистым) изменение полей своего объекта? Здесь Вы меня застали врасплох  :) Надо бы здесь хорошенько подумать, можно сообща.

Цитата: vlad
Вы не можете заранее (в абстрактном интерфейсе) определить будет ли метод функцией (const), потому что вы ничего не можете предполагать о реализации этого метода.
Да, в С++ не могу ничего утверждать. Ну, а в нашем абстрактном (пока) языке могу. Если метод в абстрактном интерфейсе был объявлен как function, то и все его реализации должны быть функциями. То есть не допускается полиморфизм такого рода, что функция в наследниках превращается в процедуру, и наоборот.

Что касается того, что чистые функции очень маленькие (игрушечные) и потому почти бесполезны, то это не справедливо по отношению к функциям. Функции могут быть исключительно сложны. Например, функция может вычислять оптимальный коэффициент по Калману для стохастической ситемы N-того порядка. Такую функцию ещё и разбивать придётся на вложенные функции. Несколько страниц точно займёт.  :D

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re:Функции против процедур
« Ответ #61 : Февраль 28, 2011, 08:32:50 pm »
Кстати, здесь встаёт интересный вопрос, а разрешить ли методам-функциям (чистым) изменение полей своего объекта?
Подобные действия со стороны какой-либо функции автоматически означают, что эта функция грязная.
« Последнее редактирование: Февраль 28, 2011, 08:38:29 pm от Geniepro »
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re:Функции против процедур
« Ответ #62 : Февраль 28, 2011, 08:34:10 pm »
Представьте себе. Сегодня вот эта функция была у нас чистая, а завтра мы решили её сделать грязной (убрали модификатор PURE и добавили в неё вывод в лог). Но при этом все выражения в которых она была использована в качестве операнда, мгновенно стали грязными. Теперь нам надо отыскать все 120 этих выражений, разбросанных по 30 модулям, и в каждом из этих случаев решить критично это изменение или нет.

Сложно представить, насколько грязной нужно сделать функцию, чтобы стало критично найти все выражения с такой функцией (в не-pure функциях)...

Цитировать
Цитата: vlad
Данные в немаленьких системах не лежат настолько открыто, чтобы функции могли "прочитать" все что нужно. Данные инкапсулированы и скрыты за абстракциями. Т.е., разделение на процедуры/функции должно распространятся и на методы (связанные процедуры/функции).
Мне кажется более правильным подход к инкапсуляции, принятый в Оберонах, нежели в классическом ООП.

В оберонах тоже есть абстрактные типы данных... Так что эта проблема для оберонов тоже актуальна.

Цитировать
Если метод в абстрактном интерфейсе был объявлен как function, то и все его реализации должны быть функциями. То есть не допускается полиморфизм такого рода, что функция в наследниках превращается в процедуру, и наоборот.

См. моей ответ Dizer. Объявляя функцию интерфейса pure, я рискую сделать фрэймворк неюзабельным, потому что никто не сможет реализовать такую функцию как pure.

Цитировать
Что касается того, что чистые функции очень маленькие (игрушечные) и потому почти бесполезны, то это не справедливо по отношению к функциям. Функции могут быть исключительно сложны. Например, функция может вычислять оптимальный коэффициент по Калману для стохастической ситемы N-того порядка. Такую функцию ещё и разбивать придётся на вложенные функции. Несколько страниц точно займёт.  :D

Это все числодробильные штуки. С ними, как я уже говорил, не очень интересно, потому что и так все легко котроллируется: входные данные известны (массивы, простые типы), смотрим чтобы такой модуль ничего лишнего не импортил (а ему и не надо) и все.
« Последнее редактирование: Февраль 28, 2011, 08:36:16 pm от vlad »

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re:Функции против процедур
« Ответ #63 : Февраль 28, 2011, 08:38:11 pm »
Насчёт DLL вопрос непонятен. У DLL есть определённый формат описания функций, содержащихся в ней, и там нет упоминаний чисты эти функции или нет, как и вообще описания типов этих функций.
Так что программа на этом гипотетическом языке по-любому должна будет воспользоваться дополнительным интерфейсом, написанным вручную для этой DLL. И вот там уже программисту, описывающему этот интерфейс, нужно думать, как описать функции в этой DLL -- как чистые или как грязные. И если он пометит как чистую функцию, грязную на самом деле, то он сам себе злобный буратина.

Если же понадобится делать что-то типа DLL, но специально для этого языка, то там всё это должно быть прописано --и тип, и чистота. Ну а то, что эта библиотека окажется несовместимой с Win32 DLL, так ни дотнетчики, ни оберонщики этим не заморачиваются...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

igor

  • Sr. Member
  • ****
  • Сообщений: 438
    • Просмотр профиля
Re:Функции против процедур
« Ответ #64 : Март 01, 2011, 05:35:33 am »
Кстати, здесь встаёт интересный вопрос, а разрешить ли методам-функциям (чистым) изменение полей своего объекта?
Подобные действия со стороны какой-либо функции автоматически означают, что эта функция грязная.
С одной стороны  это так. А с другой стороны методы для того и предназначены, чтобы изменять состояние объекта. В классическам ООП поля объектов вроде вообще нельзя изменять напрямую, только через методы. Так вот. Имеет ли смысл рассматривать поля объекта как "продолжение" результата функции? Я склоняюсь к тому, что нет, не стОит. Но полной уверенности в удачности такого решения пока нет.

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re:Функции против процедур
« Ответ #65 : Март 01, 2011, 05:41:25 am »
В классическам ООП поля объектов вроде вообще нельзя изменять напрямую, только через методы.
ООП в стиле Эрланга...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

igor

  • Sr. Member
  • ****
  • Сообщений: 438
    • Просмотр профиля
Re:Функции против процедур
« Ответ #66 : Март 01, 2011, 05:46:43 am »
Это все числодробильные штуки. С ними, как я уже говорил, не очень интересно, потому что и так все легко котроллируется: входные данные известны (массивы, простые типы), смотрим чтобы такой модуль ничего лишнего не импортил (а ему и не надо) и все.
vlad, Вы всё время подчёркиваете ограниченность применения чистых функций. Да, так и есть, их применение ограниченно. Но в этом нет большой беды, ведь процедуры-то никуда не делись, они остались с нами. Пользуйтесь наздоровье  :)
Ещё, если мы говорим об универсальном языке программирования, то неуместно говорить "это мне интересно, это - не очень". Хотя в другом контексте в этих заявлениях нет ничего плохого  :)

DIzer

  • Гость
Re:Функции против процедур
« Ответ #67 : Март 01, 2011, 06:06:47 am »
У Хаскеля статическая типизация. При статической типизации соответствие типов проверяются на этапе компиляции. Контроль побочных эффектов в хаскеле сведен к проверке типов так как описал я. Гм… Что-нибудь не ясно?
И так господа Хаскеловоды -обьяснитесь - причем тут проверка типов? - на попытку разжевывания вы потратили страницу, или в хаскеле под чистотой понимается нечто другое?

igor

  • Sr. Member
  • ****
  • Сообщений: 438
    • Просмотр профиля
Re:Функции против процедур
« Ответ #68 : Март 01, 2011, 06:11:27 am »
С ними, как я уже говорил, не очень интересно, потому что и так все легко котроллируется: входные данные известны (массивы, простые типы), ...
Нужно стремиться к тому, чтобы всё контроллировалось не только легко, но и по возможности автоматически, то есть компилятором.

Идём дальше.
Чистые функции позволяют нам ввести выражения вида: a < b < c. Что равносильно (a < b) & (b < c).
Почему эту привычную математическую нотацию нельзя ввести без требования чистоты функций? Потому что границы диапазона могут вычисляться при помощи функции:
с := 9;
IF MinVal() < b < c THEN ...
Если функция MinVal() грязная, то она может изменить переменную b и c ещё до того, как дело дойдёт до сравнения. В 90 процентах случаев - это не то, что ожидает программист.
На этом моменте долго можно не останавливаться, уже обсуждалось на OberonCore.
« Последнее редактирование: Март 01, 2011, 06:20:59 am от igor »

igor

  • Sr. Member
  • ****
  • Сообщений: 438
    • Просмотр профиля
Re:Функции против процедур
« Ответ #69 : Март 01, 2011, 06:17:46 am »
Можно привести пример и похуже:
IF a < Val() THEN ...Как насчёт постусловия a < Val()?
При сравнении будет использовано значение переменной a, которое было ДО выполнения функции Val(), или ПОСЛЕ?
« Последнее редактирование: Март 01, 2011, 06:21:50 am от igor »

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re:Функции против процедур
« Ответ #70 : Март 01, 2011, 06:24:00 am »
И так господа Хаскеловоды -обьяснитесь - причем тут проверка типов? - на попытку разжевывания вы потратили страницу, или в хаскеле под чистотой понимается нечто другое?
Любые действия, имеющие побочные эффекты, помечаются как имеющие тип IO, то есть ввод/вывод.
Если тип функции не помечен как IO, функция заведомо чистая. Типы функций контролируются системой типов. Если при проверке типа функции оказывается, что где-то внутри неё используется IO, то и вся функция помечается как имеющая тип IO.
« Последнее редактирование: Март 01, 2011, 06:26:56 am от Geniepro »
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

DIzer

  • Гость
Re:Функции против процедур
« Ответ #71 : Март 01, 2011, 07:21:08 am »
И так господа Хаскеловоды -обьяснитесь - причем тут проверка типов? - на попытку разжевывания вы потратили страницу, или в хаскеле под чистотой понимается нечто другое?
Любые действия, имеющие побочные эффекты, помечаются как имеющие тип IO, то есть ввод/вывод.
Если тип функции не помечен как IO, функция заведомо чистая. Типы функций контролируются системой типов. Если при проверке типа функции оказывается, что где-то внутри неё используется IO, то и вся функция помечается как имеющая тип IO.
Господа .... я говор про другое - в предложенном сейчас D методе - речь идет не о ТИПАХ а о ПЕРЕМЕННЫХ - это РАЗНЫЕ сущности , разве нет?

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re:Функции против процедур
« Ответ #72 : Март 01, 2011, 08:27:05 am »
Господа .... я говор про другое - в предложенном сейчас D методе - речь идет не о ТИПАХ а о ПЕРЕМЕННЫХ - это РАЗНЫЕ сущности , разве нет?
Уточни плиз, в чем вопрос. Если можно, то по подробней.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re:Функции против процедур
« Ответ #73 : Март 01, 2011, 08:54:14 am »
Господа .... я говор про другое - в предложенном сейчас D методе - речь идет не о ТИПАХ а о ПЕРЕМЕННЫХ - это РАЗНЫЕ сущности , разве нет?

"Место для D", Андрей Александреску:
Цитировать
Почему неизменяемые данные это так здорово? Совместное использование неизменяемых
данных потоками не требует синхронизации, а отсутствие синхронизации - самая быстрая
синхронизация. Хитрость в том, чтобы быть уверенным: «только для чтения» и впрямь озна-
чает «только для чтения», а иначе нельзя дать никаких гарантий. Чтобы поддержать этот
важный аспект параллельного программирования, D предоставляет беспрецедентную под-
держку для смешивания функционального и императивного программирования. Данные со
спецификатором immutable предоставляют сильные статические гарантии — правильно ти-
пизированная программа не может изменять immutable данные. Более того, неизменяемость
транзитивна, и при работе на неизменяемой территории все ссылки тоже будут указывать
на неизменяемые данные. (Почему? Если бы это было не так, то при совместном использо-
вании потоками данных, которые вы считали неизменяемыми, вы непреднамеренно делаете
общими и изменяемые данные, но в этом случае мы возвращаемся к сложным правилам
которых хотели избежать). Целые подграфы связанных объектов могут быть легко «окра-
шены» неизменяемостью. Система типов знает где они и позволяет свободно разделять их
между потоками, более агрессивно оптимизируя доступ к ним и в однопоточном коде.
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

DIzer

  • Гость
Re:Функции против процедур
« Ответ #74 : Март 01, 2011, 09:14:36 am »
Господа .... я говор про другое - в предложенном сейчас D методе - речь идет не о ТИПАХ а о ПЕРЕМЕННЫХ - это РАЗНЫЕ сущности , разве нет?

"Место для D", Андрей Александреску:
Цитировать
Почему неизменяемые данные это так здорово? Совместное использование неизменяемых
данных потоками не требует синхронизации, а отсутствие синхронизации - самая быстрая
синхронизация. Хитрость в том, чтобы быть уверенным: «только для чтения» и впрямь озна-
чает «только для чтения», а иначе нельзя дать никаких гарантий. Чтобы поддержать этот
важный аспект параллельного программирования, D предоставляет беспрецедентную под-
держку для смешивания функционального и императивного программирования. Данные со
спецификатором immutable предоставляют сильные статические гарантии — правильно ти-
пизированная программа не может изменять immutable данные. Более того, неизменяемость
транзитивна, и при работе на неизменяемой территории все ссылки тоже будут указывать
на неизменяемые данные. (Почему? Если бы это было не так, то при совместном использо-
вании потоками данных, которые вы считали неизменяемыми, вы непреднамеренно делаете
общими и изменяемые данные, но в этом случае мы возвращаемся к сложным правилам
которых хотели избежать). Целые подграфы связанных объектов могут быть легко «окра-
шены» неизменяемостью. Система типов знает где они и позволяет свободно разделять их
между потоками, более агрессивно оптимизируя доступ к ним и в однопоточном коде.
Может не будем уподобляться Илье ...А (или вы хотите свести общение на форуме, к обмену цитатами от балды ?)  :( - для этого есть oberoncore...