Вопрос: Чем отличаются друг от друга функции, процедуры и операторы(на примере FreePascal)?

Лучший ответ: Функции и процедуры - почти одно и то же. Различие лишь в том, что функция возвращает значение, а процедура - нет. Очевидно, функцию можно использовать, как процедуру, если просто игнорировать возвращаемое значение. Поэтому в других языках обычно даже не вводится такое понятие, как процедура. А в Си-подобных языках, где функция обязана иметь возвращаемый тип, используется тип void, что тоже как бы делает функцию процедурой.

Говоря о функциях или процедурах, акцент ставится на сам механизм вызова - указатель текущего места выполнения помещается в стек, управление передаётся функции, и по её завершении указатель восстанавливается из стека и выполнение программы продолжается с того же места. Таким образом, имеются в виду два момента: 1) сам вызов функции 2) расположение тела функции в другом месте памяти. То есть функция - по сути подпрограмма.

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

Худший ответ: Процедуры не возвращают результат, функции — возвращают.

$X (eXtended syntax)Эта разница осложняется тем, что Паскаль после Вирта чаще портят, чем делают лучше. И, например, сделали возможным выбрасывать результат функции и вызывать функцию как процедуру. В Delphi это регулируется директивой $X (eXtended syntax), который паровозом меняет сразу много всего, и нельзя по отдельности только запретить выбрасывать результат. Паровозом становится нельзя образаться к результату по имени переменной Result. Казалось бы, можно пользоваться Exit(значение), но компилятор начинает глючить, когда тип значения record с управлением владением. И буфер символов array[0 .. 1023] of Char становится сложнее превратить в строку. Также становится обязательно использовать каретку для разыменования указателей. Смешались в кучу кони, люди. Куча синтаксических отличий переключается одной директивой, и сделано так, что с выключенной директивой толком жить не получается. Может быть, в FPC иначе, там свои глюки.

Что касается операторов, в русском языке есть путаница переводов слов, которые в английском языке сильно не похожи. Хорошие переводчики разрешили эту путаницу таким образом, что statement = оператоР, а operator = операЦИЯ. Но не все переводчики согласовали глоссарий.

Оператор (statement) — это:

пустой оператор
присваивание
вызов процедуры
составной оператор begin оператор; оператор; … end;
прочие операторы, как goto, raise, try, if, for, while, repeat


Операция (operator) — это:

сложение, вычитание, умножение, деление
сравнения
логические и побитовые операции and, xor, or, not
битовые сдвиги shl, shr
явные и неявные приведения типов


В Delphi 2006 и выше для объявления собственных операторов используется синтаксис class operator. У Free Pascal тоже был свой синтаксис собственных операторов.

Здесь может быть путаница, потому что в Pascal не все операторы являются честными операторами, как должно быть. Например, Exit, Break и Continue не являются синтаксически простыми операторами, а являются операторами-вызовами процедуры, и расположены эти специальные процедуры в модуле System, так что полное имя System.Exit тоже сработает.

Автор учебника, наверное, думает, что Read и ReadLn, наоборот, являются простыми операторами. Но нет. Это процедуры из модуля System, на которые навешана магия компилятора, чтоб они принимали разные параметры, но эта магия не делает из них операторы. Хотя вызов процедуры — это формально оператор.