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

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Функции против процедур
« : Февраль 27, 2011, 03:19:08 am »
Обсуждение как-то затерялось в общем потоке, поэтому решил выделить в отдельную тему.
Итак, из того, что было сказано, я понял, что смысл разделения процедура функция сводится к (поправьте):
1. Функция не имеет побочных эффектов.
2. Процедура не возвращает значения (или косвенно возвращает через OUT-аргументы).

По поводу пункта 1 у меня никаких возражений нет - да, хочется контролировать побочные эффекты. И такое разделение иметь полезно, пока мы имеем некий компромиссный ЯП (не хаскель ;)
По поводу пункта 2 - вообще непонятно зачем такое ограничение. Пусть возвращает нормальный результат. Зачем кому-то нужны OUT-параметры?

Далее по реализации. Если брать за базу оберон, то какие изменения нужны в языке, чтобы обеспечить пункт 1? Если ничего нельзя сделать - тогда извините, но такое разделение совсем не нужно и плодит лишние сущности.
Конкретно хочется услышать ответ на вопрос: если мы запрещаем из функции обращение ко всем "внешним" сущностям и ограничиваем аргументы простыми типами (даже не процедурными) - то что полезного можно получить из таких функций.

igor

  • Sr. Member
  • ****
  • Сообщений: 438
    • Просмотр профиля
Re:Функции против процедур
« Ответ #1 : Февраль 27, 2011, 06:35:48 am »
Конкретно хочется услышать ответ на вопрос: если мы запрещаем из функции обращение ко всем "внешним" сущностям и ограничиваем аргументы простыми типами (даже не процедурными) - то что полезного можно получить из таких функций.
Не "запрещаем", а "разрешаем только для чтения". Эти "внешние" сущности вполне могут выступать в качестве первичных данных, наряду с параметрами функции.

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re:Функции против процедур
« Ответ #2 : Февраль 27, 2011, 02:58:25 pm »
Конкретно хочется услышать ответ на вопрос: если мы запрещаем из функции обращение ко всем "внешним" сущностям и ограничиваем аргументы простыми типами (даже не процедурными) - то что полезного можно получить из таких функций.
Не "запрещаем", а "разрешаем только для чтения". Эти "внешние" сущности вполне могут выступать в качестве первичных данных, наряду с параметрами функции.

Поясните пожалуйста. Что значит для чтения? Вызывать другие функции очевидно можно? А процедуры?

igor

  • Sr. Member
  • ****
  • Сообщений: 438
    • Просмотр профиля
Re:Функции против процедур
« Ответ #3 : Февраль 27, 2011, 03:33:05 pm »
Поясните пожалуйста. Что значит для чтения? Вызывать другие функции очевидно можно? А процедуры?
"Разрешены только для чтения" - это значит они могут быть использованы в качестве операнда в выражении, но им самим ничего нельзя присваивать.
Внутри описания функции могут быть вызовы других функций. Вызовы процедур в теле функции запрещены (правило 3), так как эти процедуры могут изменить глобальное состояние программы.

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re:Функции против процедур
« Ответ #4 : Февраль 27, 2011, 03:42:04 pm »
Поясните пожалуйста. Что значит для чтения? Вызывать другие функции очевидно можно? А процедуры?
"Разрешены только для чтения" - это значит они могут быть использованы в качестве операнда в выражении, но им самим ничего нельзя присваивать.
Внутри описания функции могут быть вызовы других функций. Вызовы процедур в теле функции запрещены (правило 3), так как эти процедуры могут изменить глобальное состояние программы.

Ага. Т.е., у нас остаются только глобальные переменные на чтение и другие функции. Правильно? И чего полезного такие функции могут посчитать?

P.S. Пока это очень похоже на плюсовый const, за исключением доступа к внешним сущностям.

igor

  • Sr. Member
  • ****
  • Сообщений: 438
    • Просмотр профиля
Re:Функции против процедур
« Ответ #5 : Февраль 27, 2011, 03:48:59 pm »
И чего полезного такие функции могут посчитать?
Вторичные данные. То есть те данные, которыми мы не располагали до вызова функции.
Вопросики какие-то детские пошли  :D

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re:Функции против процедур
« Ответ #6 : Февраль 27, 2011, 03:58:57 pm »
Ну, т.е. в лог например такая функция уже ничего не запишет.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

igor

  • Sr. Member
  • ****
  • Сообщений: 438
    • Просмотр профиля
Re:Функции против процедур
« Ответ #7 : Февраль 28, 2011, 06:41:35 am »
Писать в лог всё-же лучше в том блоке, в котором содержится вызов процедуры. IMHO.

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re:Функции против процедур
« Ответ #8 : Февраль 28, 2011, 07:15:27 am »
Писать в лог всё-же лучше в том блоке, в котором содержится вызов процедуры. IMHO.
+1

А то вчера функция была чистой, сегодня она должна что-то в лог писать, завтра ей понадобится из этого лога читать и менять результаты расчётов...
Что-то не то с этой функцией, неправильно как-то всё это...

Если нужно проверить работу функции -- так юнит-тесты для этого придуманы...
to iterate is human, to recurse, divine

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

igor

  • Sr. Member
  • ****
  • Сообщений: 438
    • Просмотр профиля
Re:Функции против процедур
« Ответ #9 : Февраль 28, 2011, 07:25:03 am »
Писать в лог всё-же лучше в том блоке, в котором содержится вызов процедуры. IMHO.
Sorry, опечатался...  :-\\ Вызов функции конечно, а не процедуры.
Ну, Geniepro правильно меня понял.  :)

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re:Функции против процедур
« Ответ #10 : Февраль 28, 2011, 07:31:06 am »
В этом плане у Хаскелла подход прост и прямолинеен:

Нужны функции, имеющие доступ к вводу/выводу и прочим прелестям побочных эффектов? Да нет проблем!
Но! Такая функция должна быть помечена как грязная, то есть имеющая побочные эффекты, и использовать её можно только в таких же грязных функциях. С проверкой компилятором, естественно.

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

Upd. В некоем абстрактном языке можно считать, что функции -- всегда чисты, а процедуры имеют побочные эффекты. Тогда в процедурах можно вызывать функции, а вот в функциях вызывать процедуры нельзя.
Более того, вся работа с изменяемой памятью -- присваивания там всякие -- автоматически помечается как процедурная.
« Последнее редактирование: Февраль 28, 2011, 07:35:45 am от Geniepro »
to iterate is human, to recurse, divine

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

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re:Функции против процедур
« Ответ #11 : Февраль 28, 2011, 07:34:33 am »
В хаскеле таки чистые функции могут писать в лог посредством монады Writer. От этого они менее чистыми не становятся :-)
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

DIzer

  • Гость
Re:Функции против процедур
« Ответ #12 : Февраль 28, 2011, 08:37:24 am »
Писать в лог всё-же лучше в том блоке, в котором содержится вызов процедуры. IMHO.
Проблема в том, что это не всегда возможно... Но все же что мы имеем...1. Пусть разделение на Ф и П продиктовано вами чисто из побуждения избавиться от побочного эффекта  - произойдет ли это даже если ваши предложения будут реализованы  ЯП? 2. Пусть Вы вводите это разделение просто для того, чтобы разделить "Чистые" и "Грязные" действия- насколько предложенная Вами форма адекватна цели... и вообще насколько это реализуемо на практике в компилляторах (т.е. проверка чистоты на низком уровне для проекта произвольной сложности). всегда ли она возможна?

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re:Функции против процедур
« Ответ #13 : Февраль 28, 2011, 08:41:45 am »
2. Пусть Вы вводите это разделение просто для того, чтобы разделить "Чистые" и "Грязные" действия- насколько предложенная Вами форма адекватна цели... и вообще насколько это реализуемо на практике в компилляторах (т.е. проверка чистоты на низком уровне для проекта произвольной сложности). всегда ли она возможна?
Однако трансляторы Хаскелла показывают, что это вполне возможно и реализуемо.
to iterate is human, to recurse, divine

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

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re:Функции против процедур
« Ответ #14 : Февраль 28, 2011, 08:51:47 am »
Эта проверка вообще делается не на уровне компилятора, а посредством системы типов. Система типов естественно нужна сильнее нежели в обероне, или даже Аде. Ну и естественно побочные эффекты должны быть возможны только через стандартную библиотеку (где уже все это типизировано как надо).

Либо поддержку этой штуки (разделение на чистое и не чистое) закладывать непосредственно в язык, т.e. вместо общего решения получим частное, тогда да, поддержка со стороны компилятора нужна.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"