Зачем проводить различие между методами, которые возвращают значение, и методами, которые этого не делают? - PullRequest
5 голосов
/ 19 июня 2009

Почему некоторые языки различают методы, возвращающие значение, и методы, которые этого не делают?

т.е. в Oracle PL / SQL, где основное различие между функцией и процедурой заключается в том, что функция должна возвращать значение, а процедура - нет.

Аналогично для языков, которые этого не делают, почему бы и нет?


РЕДАКТИРОВАТЬ: Я нашел связанный вопрос, который может заинтересовать людей, читающих этот вопрос:

Ответы [ 3 ]

26 голосов
/ 19 июня 2009

Поскольку в первоначальных концепциях теории и практики информатики функции и подпрограммы практически не имели ничего общего друг с другом.

Фортран обычно считается первым языком, который реализовал оба из них и продемонстрировал различия.(Ранний LISP также играл в этом несколько противоположную роль, но он оказал незначительное влияние за пределами академического сообщества).

Исходя из традиций математики (частью которой в 60-е годы был еще CS), функции рассматривались только как инкапсуляция параметризованных математических вычислений, предназначенных исключительно для возврата значения в большее выражение.То, что вы могли бы назвать это «голым» (F = AZIMUTH (SECONDS)), было просто тривиальным случаем использования.

Подпрограммы, с другой стороны, рассматривались как способ назвать группу операторов, предназначенную для некоторыхэффект.Параметры значительно повысили их удобство использования, и единственная причина, по которой им было разрешено возвращать измененные значения параметров, заключалась в том, что они могли сообщать о своем состоянии, не полагаясь на глобальные переменные.

Таким образом, у них действительно не было концептуальныхсвязь, кроме инкапсуляции и параметров.

Реальный вопрос: «Как так много разработчиков пришли к мнению, что они одинаковые?»

И ответом на это является C.

Когда K + R изначально разработали свой высокоуровневый язык типов макро-ассемблера для PDP-11 (возможно, начался на PDP-8?), У них не было иллюзий аппаратной независимости.Практически каждая «уникальная» особенность языка была отражением машинного языка и архитектуры PDP (см. I ++ и --i).Одним из них было осознание того, что функции и подпрограммы могут быть (и всегда были) реализованы одинаково в PDP, за исключением того, что вызывающая сторона просто игнорировала возвращаемое значение (в R0 [, R1]) для подпрограмм.

Так родился указатель void, и после того, как язык C захватил весь мир программирования, ошибочное представление о том, что этот артефакт реализации HW / OS (правда, почти на каждой последующей платформе) был таким же, каксемантика языка.

3 голосов
/ 19 июня 2009

В чистой или типизированной настройке есть большая разница, потому что очевидно, что методы, которые «ничего не возвращают», полезны только для их побочных эффектов.

Это аналогично различию между выражениями и утверждениями, которое может очищать язык от языка и исключать класс обычно ошибочных программ (что, разумеется, почему C не делает этого;)).

Чтобы привести один крошечный пример, когда вы четко различаете выражения и операторы, if(x = 3), в отличие от if(x == 3), синтаксически некорректен (для использования оператора, где ожидалось выражение), а не просто ошибка типа (для используя целое число, где ожидалось логическое значение). Преимуществом этого является также запрет if(x = true), который был бы разрешен правилом на основе типов в контексте, где присваивания являются выражениями, которые имеют значение своего правого операнда.

В языке, в котором эффекты заключены в монады, важное различие становится между:

  • функции, которые возвращают (), которые являются чистыми функциями и могут возвращать только одно бесполезное пустое значение с именем () или расходятся
  • функции, которые возвращают IO () (или единицу в некоторой другой монаде), которые являются функциями без «результата», кроме эффектов в IO (или любой другой) монаде
0 голосов
/ 10 января 2012

Извините, что отвечаю на двухлетний вопрос, особенно с чем-то уникальным для моего собственного языка. Феликс http://felix -lang.org , но здесь все равно идет:)

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

Нет, модель исполнения принципиально отличается, в первую очередь, из соображений производительности, но не полностью. Модель:

  • Функции помещают свой адрес возврата в стек компьютера, а также возвращаемое значение.
  • Процедуры используют связанный список в куче. Процедурный код плоский, он не использует машинный стек.

Это обычно неэффективно, так зачем это делать? Ответ таков: все процедуры Феликса - это потенциально сопрограммы (волокна). Они могут переключить управление на другую процедуру, получив доступ к каналу. Это вызывает обмен контролем.

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

ОС обычно меняет указатели стека на потоки, что является достаточно быстрым, но имеет фундаментальную проблему на машинах с линейными адресами: вы должны либо ограничить максимальный размер стека до смехотворно небольшого значения, либо ограничить количество потоков до смехотворно малого значения. На 32-битной машине недостаточно адресного пространства, чтобы даже обдумать это решение. На 64-битной машине обмен стека имеет больший потенциал, но, конечно, требования пользователей всегда растут, чтобы опередить аппаратное обеспечение через 3 дня после его выпуска ..:)

Феликс просто меняет один указатель на стеки, основанные на куче, поэтому переключение контекста ослепительно быстро и очень мало адресного пространства тратится впустую. Конечно, затраты на выделение кучи при вызове процедур расходуются.

В компиляторе большая часть архитектуры теоретической модели оптимизируется по принципу «как будто», поэтому фактическая производительность и реализация могут сильно отличаться от теоретической модели, если компилятор может доказать, что вы можете не говорите разницу .. кроме того, что вам отказывают в возможности сделать чашку кофе с досугом:)

Итак, у вас есть другой ответ, почему функции и процедуры могут трактоваться по-разному.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...