История изменений
Исправление liksys, (текущая версия) :
Раз ты сподобился развернуть догмы, то я объясню, в чем тут проблема.
Процедура — подпрограмма, которая вызывается ради некоторого эффекта… Столяров предлагает выдерживать строгое разделение между процедурами и функциями. То есть если требуется значение, то использовать функцию и в ней не делать ничего кроме вычисления этого значения. Если требуется эффект, то следует использовать процедуру.
Это разделение существует только в голове столярова, и в реальности не встречается нигде, кроме учебных упражнений. Более того, побочным эффектом можно назвать всё что угодно, в зависимости от точки отсчета. Побочных эффектов не бывает только у простейших функций, выполняющих преобразования данных, и то с натяжкой.
У процедуры в паскале нет возвращаемого значения, но есть var, которое семантически является абсолютно тем же самым. Ты вызываешь процедуру, и данные в вызывающей функции меняются, это локальный побочный эффект. Вызываешь сишную функцию, передав указатели, и можешь сделать ровно то же самое. Надо получить код результата процедуры? Передаешь еще один var в паскале, а в си, по соглашению, возвращаешь чиселку. То есть вся проблема из-за того, что функция не должна ничего менять у вызывающего, а процедура - может.
- Функция, принимающая две строки и возвращающая выделенную память с новой строкой - она с побочным эффектом или нет? Вроде нет, но количество памяти процесса меняется, значит эффект есть.
- Математическая функция, делающая сложные вычисления. Вроде бы у нее побочного эффекта нет, но если ты добавишь логгирование промежуточных вычислений, то он появляется, или нет? Ведь на консоль выводятся значения.
- А вот запись на диск, которая, по идее, должна быть процедурой с побочным эффектом, на самом деле будет функцией, потому что кроме побочного эффекта записи на диск у тебя будет результат исполнения, который в случае си станет возвращаемым значением.
По сути, столяровские пляски вокруг побочного эффекта это просто семантика паскаля, которую столяров решил возвести в абсолют. Теперь, когда мы выяснили, что побочный эффект существует практически всегда, неплохо бы понять, что с этим делать. Наибольшую проблему в случае побочных эффектов представляют функции, имеющие дополнительную связь через глобальные переменные. Это перекликается с декомпозицией задачи, которую обязательно следует объяснять студенту: вот у него есть функция чтения из терминала, вот функция печати, а вот - вычисление квадратного корня. И если он организует их общение через глобальные переменные, он просто не сможет взять функцию квадратного корня и попытаться вычислить несколько значений независимо друг от друга, или провести изолированное тестирование функции, чтобы убедиться, что она работает корректно.
Вот это - наиболее важный аспект: научить разбивать задачу на изолированные подзадачи и контроллировать их исполнение. Важно дать понимание, что следует минимизировать влияние кода на глобальное состояние системы. Но это не нужно на начальных этапах обучения, когда студент просто осваивает простейшие языковые конструкции. На поздних же этапах процедуры в формате столярова почти исчезнут из кода, и останутся только функции, так что забивание головы этим разделением изначально не имеет никакого смысла.
Исходная версия liksys, :
Раз ты сподобился развернуть догмы, то я объясню, в чем тут проблема.
Процедура — подпрограмма, которая вызывается ради некоторого эффекта… Столяров предлагает выдерживать строгое разделение между процедурами и функциями. То есть если требуется значение, то использовать функцию и в ней не делать ничего кроме вычисления этого значения. Если требуется эффект, то следует использовать процедуру.
Это разделение существует только в голове столярова, и в реальности не встречается нигде, кроме учебных упражнений. Более того, побочным эффектом можно назвать всё что угодно, в зависимости от точки отсчета. Побочных эффектов не бывает только у простейших функций, выполняющих преобразования данных, и то с натяжкой.
- Функция, принимающая две строки и возвращающая выделенную память с новой строкой - она с побочным эффектом или нет? Вроде нет, но количестсо памяти процесса меняется, значит эффект есть.
- Математическая функция, делающая сложные вычисления. Вроде бы у нее побочного эффекта нет, но если ты добавишь логгирование промежуточных вычислений, то он появляется, или нет? Ведь на консоль выводятся значения.
- А вот запись на диск, которая, по идее, должна быть процедурой с побочным эффектом, на самом деле будет функцией, потому что кроме побочного эффекта записи на диск у тебя будет результат исполнения, который в случае си станет возвращаемым значением.
У процедуры в паскале нет возвращаемого значения, но есть var, которое семантически является абсолютно тем же самым. Ты вызываешь процедуру, и данные в вызывающей функции меняются, это локальный побочный эффект. Вызываешь сишную функцию, передав указатели, и можешь сделать ровно то же самое. Надо получить код результата процедуры? Передаешь еще один var в паскале, а в си, по соглашению, возвращаешь чиселку.
По сути, это просто семантика языка, которую столяров решил возвести в абсолют. Теперь, когда мы выяснили, что побочный эффект существует практически всегда, неплохо бы понять, что с этим делать. Наибольшую проблему в случае побочных эффектов представляют функции, имеющие дополнительную связь через глобальные переменные. Это перекликается с декомпозицией задачи, которую обязательно следует объяснять студенту: вот у него есть функция чтения из терминала, вот функция печати, а вот - вычисление квадратного корня. И если он организует их общение через глобальные переменные, он просто не сможет взять функцию квадратного корня и попытаться вычислить несколько значений независимо друг от друга, или провести изолированное тестирование функции, чтобы убедиться, что она работает корректно.
Вот это - наиболее важный аспект: научить разбивать задачу на изолированные подзадачи и контроллировать их исполнение. Важно дать понимание, что следует минимизировать влияние кода на глобальное состояние системы. Но это не нужно на начальных этапах обучения, когда студент просто осваивает простейшие языковые конструкции. На поздних же этапах процедуры в формате столярова почти исчезнут из кода, и останутся только функции, так что забивание головы этим разделением изначально не имеет никакого смысла.