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

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re:Функции против процедур
« Ответ #90 : Март 01, 2011, 02:29:35 pm »
Это все числодробильные штуки. С ними, как я уже говорил, не очень интересно, потому что и так все легко котроллируется: входные данные известны (массивы, простые типы), смотрим чтобы такой модуль ничего лишнего не импортил (а ему и не надо) и все.
vlad, Вы всё время подчёркиваете ограниченность применения чистых функций. Да, так и есть, их применение ограниченно. Но в этом нет большой беды, ведь процедуры-то никуда не делись, они остались с нами. Пользуйтесь наздоровье  :)

Беды конечно нет, кроме часто упоминаемой оберонщиками "усложнения языка из-за ничего". Просто вполне естественно приоритезировать величину граблей. И с этой точки зрения невозможность "безопасно" писать "a < b < c" или даже просто "a < f()" - да, грабли, но очень маленькие. Например, в С++ порядок вычисления выражения и аргументов функций неопределен. Все об этом знают (или узнают, наступив на грабли) и если этот порядок важен или вызов функции может иметь побочный эффект на другие операнды выражения, то предпринимают  соответствующие действия. Предложенный вариант в виде pure функций и различия в синтаксисе вызова pure/не-pure гарантирует отсутствие этих граблей. Это очень хорошо. С одной стороны. С другой - мы уже не можем написать что-то совершенно простое и естественное а-ля: "x + window.width()". Если предположить, что у нас большая часть функций будет pure - с этим можно мирится, больше поводов будет делать функции pure (а это хорошо). Но если у нас pure-функций меньшинство - то я лучше оставлю эти маленькие грабли нерешенными в угоду более ясному коду в большинстве ситуаций.

Цитировать
Ещё, если мы говорим об универсальном языке программирования, то неуместно говорить "это мне интересно, это - не очень". Хотя в другом контексте в этих заявлениях нет ничего плохого  :)

А вот пример больших граблей, на которые не хочется наступать в более правильных универсальных языках :) Есть древнючий код (~10 лет) с накопленной за все эти годы спецификой, заплатками и т.д. Код, конечно, гхм... плохой. И не потому, что его писали неумные люди или там ополченцы. Просто он старый. И мне его надо заставить работать в отдельном потоке. Не переписывая на хаскеле :) Условие "не переписывать" исходит не из того, что я такой ленивый, а из того, что я в принципе не могу выковырять из него всей накопленной "специфики" поведения и не сломать какой-то сценарий при переписывании. Вот моя мечта: я помечаю функцию-вход всего этого безобразия как pure (или там thread или еще как) и просто исправляю ошибки компиляции. Исправляю, конечно, не автоматически, но полуавтоматически. Если будет какой-то кусочек, который в принципе несовместим с работой в отдельном потоке - я его перепишу правильно. Но только это будет кусочек, а не вся эта аморфная куча. Компиляция прошла - код гарантировано заработал. Без трудноуловимых багов, специфичных для многопоточности. Только не надо кивать на ортогональные вещи типа тестов, строгих спецификаций и т.д. Это все классно, но такой код все равно был, есть и будет.
« Последнее редактирование: Март 01, 2011, 02:33:23 pm от vlad »

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re:Функции против процедур
« Ответ #91 : Март 01, 2011, 02:40:18 pm »
2 vlad: ты мне обещал примерчиков :-) Так что милости прошу, так сказать :-)

Да трудно придумать такую задачку. Все самое интересное начинается в больших задачах. Пока не знаю, что предложить.

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re:Функции против процедур
« Ответ #92 : Март 01, 2011, 02:46:41 pm »
2vlad: тебе в этой задаче не нужно чтобы код был чистым, то есть без побочных эффектов, тебе нужно чтобы побочные эффекты были локализованы, инкапсулированы внутри этого кода, или были бы и во вне, но их было бы явно видно. То есть тебе нужно ровно то, о чем я говорил – явное разграничение доступа, которое контролируется компилятором.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re:Функции против процедур
« Ответ #93 : Март 01, 2011, 03:04:27 pm »
Т.e. нужно уметь сказать, что вот этот вот код не должен менять что-либо о чем я знаю (список исключений из правила прикладывается), и компилятор должен суметь это проконтроллировать.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re:Функции против процедур
« Ответ #94 : Март 01, 2011, 03:05:40 pm »
2vlad: тебе в этой задаче не нужно чтобы код был чистым, то есть без побочных эффектов, тебе нужно чтобы побочные эффекты были локализованы, инкапсулированы внутри этого кода, или были бы и во вне, но их было бы явно видно. То есть тебе нужно ровно то, о чем я говорил – явное разграничение доступа, которое контролируется компилятором.

Да, я понимаю, что обсуждаемое pure - это не совсем та опера. Но близко :) Контроль за доступом к внешним штукам - тоже нужен в каком-то виде.

DIzer

  • Гость
Re:Функции против процедур
« Ответ #95 : Март 01, 2011, 03:07:37 pm »
2vlad: тебе в этой задаче не нужно чтобы код был чистым, то есть без побочных эффектов, тебе нужно чтобы побочные эффекты были локализованы, инкапсулированы внутри этого кода, или были бы и во вне, но их было бы явно видно. То есть тебе нужно ровно то, о чем я говорил – явное разграничение доступа, которое контролируется компилятором.
Либо какой- то анализатор кода,еще лучше... задача через чур специфичиская. Кстати , тут пожалуй проверка IsPure  самое то?
« Последнее редактирование: Март 01, 2011, 03:11:09 pm от DIzer »

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re:Функции против процедур
« Ответ #96 : Март 01, 2011, 03:13:47 pm »
Анализатор кода… Гм. А ведь это идея. Можно написать анализатор какого-нибудь Оберона (это вроде бы должно быть просто), который введет понятие контроля доступа (посредством анотаций, или вообще в виде спец-коментариев/прагм) и попробовать отрефакторить какой-нибудь существующий кусок реального кода например.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re:Функции против процедур
« Ответ #97 : Март 01, 2011, 03:21:00 pm »
То есть задача №1: распихивание старого кода (причем такого, который знать не знал про многопоточность) по потокам.

Между прочим, эта же задача – задача вытскивание некой функциональности в отдельную утилиту например.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re:Функции против процедур
« Ответ #98 : Март 01, 2011, 03:25:53 pm »
Речь о том - нужно ли нам порождать чистые пользовательские типы - формально -добавлять метку pure в определение типа...  ;)
Пока мне кажется, что без этого не обойтись.

Тут вообще надо сначала решить -- а нужно ли разделять подпрограммы на функционально чистые и императивно грязные.
Такое разделение даёт определённые удобства и налагает определённые неудобства.

Так же как оператор GOTO -- можно всё сделать с его помощью, но всё же на каких-то задачах удобнее и безопаснее пользоваться операторами IF, WHILE, FOREACH и т.д.
to iterate is human, to recurse, divine

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

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re:Функции против процедур
« Ответ #99 : Март 01, 2011, 03:28:16 pm »
То есть задача №1: распихивание старого кода (причем такого, который знать не знал про многопоточность) по потокам.

Между прочим, эта же задача – задача вытскивание некой функциональности в отдельную утилиту например.
Хотя нет, не та же. Вторая задача много проще.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re:Функции против процедур
« Ответ #100 : Март 01, 2011, 03:32:41 pm »
Какую задачку – не знаю. Любую реальную, достаточно большую для того, чтобы имело смысл архитектуру разводить. У меня в голове вертятся либо какие-то телекомные задачки, или какой-нибудь гуй. Важно чтобы эту задачу понимали все участвующие в дискуссии.
Вот на примере GUI-фрэймворка было бы интересно (для меня, по крайней мере).
Сейчас эти задачи решаются в основном в ООП-стиле -- довольно удобен он для этого.
Было бы интересно, какие ещё принципиальные решения могут быть.

Например -- некий GUI-engine предоставляет взаимодействие с пользователем в виде:

Мир (экран, клавиатура, мышь, аудио) => Программа => Мир (экран, клавиатура, мышь, аудио)

Если не вдаваться в низкоуровневые подробности этого GUI-engine, то Программа становится вполне функционально чистой. Насколько это реально удобно, какие могут быть недостатки?

Как можно реализовать этот GUI-engine?
to iterate is human, to recurse, divine

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

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re:Функции против процедур
« Ответ #101 : Март 01, 2011, 03:35:06 pm »
1) Когда будут выполняться эти проверки?
1 Во время выполнения
Динамические проверки малополезны.

Всё, что может быть проверено на стадии компиляции, должно быть проверено на стадии компиляции. В этом случае минимизируется цена исправления ошибок.
to iterate is human, to recurse, divine

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

DIzer

  • Гость
Re:Функции против процедур
« Ответ #102 : Март 01, 2011, 03:37:36 pm »
Речь о том - нужно ли нам порождать чистые пользовательские типы - формально -добавлять метку pure в определение типа...  ;)
Пока мне кажется, что без этого не обойтись.

Тут вообще надо сначала решить -- а нужно ли разделять подпрограммы на функционально чистые и императивно грязные.
Такое разделение даёт определённые удобства и налагает определённые неудобства.

Так же как оператор GOTO -- можно всё сделать с его помощью, но всё же на каких-то задачах удобнее и безопаснее пользоваться операторами IF, WHILE, FOREACH и т.д.
Подпрограммы всего лишь - отображение на ЯП, свойств моделируемой системы... Если решать его вообще ( то есть с позиции- ЯП может описывать ЛЮБУЮ систему , решать любую задачу) - вопрос филосовский - делить мир на "грязный" и "чистый" или нет...Чистые функциональные языки мне этим и не нравятся...как и тотально объектно =ориентированные... у них перекосы. Тут еще дело в том. что гадить может сам ЯП как своими артефактами так и идущими от железяки
« Последнее редактирование: Март 01, 2011, 03:44:23 pm от DIzer »

DIzer

  • Гость
Re:Функции против процедур
« Ответ #103 : Март 01, 2011, 03:54:42 pm »
Кстати, господа для меня лично польза от конкретно этого обсуждения есть - я ТОЧНО понял, что одно только стремление к чистоте НИКОГДА не заставит меня подсесть на Хаскель  :)

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re:Функции против процедур
« Ответ #104 : Март 01, 2011, 04:19:26 pm »
Кстати, господа для меня лично польза от конкретно этого обсуждения есть - я ТОЧНО понял, что одно только стремление к чистоте НИКОГДА не заставит меня подсесть на Хаскель  :)
А что заставит? :)

Лично меня заставил синтаксис... ;D
to iterate is human, to recurse, divine

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