Метод проти функції та процедури


107

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

Які "правильні" визначення "процедури", "методи", "функції", "підпрограми" тощо?


4
ви відмовилися від "рутини"
mefisto

1
@teresko: Я думаю, що "підпрограма" є більш поширеною.
mk12

Відповіді:


108

Тут я йду з іншою відповіддю: практично кажучи, різниці насправді немає , за тим невеликим винятком, що "метод" зазвичай посилається на підпрограму, пов'язану з об'єктом в мовах ОО.

Усі терміни "процедура, функція, підпрограма, підпрограма та метод" означають одне і те ж: підпрограма, яку можна викликати у межах більшої програми. Але важко придумати визначення, яке фіксує всі варіанти використання цих термінів, оскільки вони не використовуються послідовно в мовах програмування чи парадигмах.

Можна сказати, що функція повертає значення. Ну, наступна функція C не повертає значення:

void f() { return; }

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

Звичайно, у Pascal процедури не повертають значення, а функції повертають значення, але це лише відображення того, як Pascal був розроблений. У Fortran функція повертає значення, а підпрограма повертає кілька значень. І все ж ніщо з цього насправді не дозволяє нам придумати «універсальне» визначення для цих термінів.

Насправді, термін "процедурне програмування" відноситься до цілого класу мов, включаючи C, Fortran і Pascal, лише одна з яких насправді використовує термін "процедура", щоб означати що-небудь.

Отже, нічого з цього насправді не відповідає. Винятком є, ймовірно, "метод", який, здається, використовується майже повністю з мовами OO, посилаючись на функцію, пов'язану з об'єктом. Хоча, навіть це не завжди відповідає. Наприклад, C ++ зазвичай використовує термін "членська функція", а не метод, (хоча термін "метод" проник в просторічку C ++ серед програмістів.)

Справа в тому, що нічого з цього насправді не відповідає. Він просто відображає термінологію, якою користуються будь-які мови в той час.


Саме це я вважав відповіддю. (Я мав би додати "підпрограму" як інший варіант заднього огляду.) Чи можу я запитати: Чому б ти не знайшов того, хто називає цю функцію "процедурою"? Тому що це технічно некоректно чи тому, що термін "процедура" наразі не виходить з ладу?
Джанго Райнхардт

7
Програмісти на C використовують термін "функція" просто тому, що дизайнери C використовували цей термін.
Чарльз Сальвія

15
Не будемо викидати дитину разом з водою. Тільки тому, що термінологія не використовується з повною послідовністю, не означає, що різні терміни не мають різного значення. Визначення @ Брюса і @ Франка широко визнані, а не ідіосинкратичні. Те, що значення не є універсальними, є важливим, але це не виправдовує стрибок до "практично кажучи, різниці немає". (@Django)
LarsH

9
Вид подвійний на C ++, який називає методи "членами функції", функції Java та C # виклики "статичними методами".
Йорг W Міттаг

2
Відповідь Брюса, безумовно, є тією, до якої слід піти, якщо ви новачок у програмуванні. Його визначення будуть абсолютно правильними, 99% часу. Але я шукав більше технічної / теоретичної відповіді. Іноді новіші програмісти знають лише власний домен і наполягають на тому, що все є. Насправді сьогодні існують програмісти, які все ще використовують старі мови, і які не «помиляються» у використанні різних визначень. Мене це найбільше зацікавило.
Джанго Райнхардт

67

Функція повертає значення, але процедура не робить.

Метод схожий на функцію, але внутрішньої по відношенню до частини класу. Термін метод використовується майже виключно в об'єктно-орієнтованому програмуванні.


8
Не зовсім внутрішній. Метод - це будь-яка функція або процедура, яка є частиною класу.
Скотт Вітлок

8
Отже, "Збережена процедура" в SQL не повертає жодних значень? А як щодо "Процедури" у чомусь на зразок Паскаля? Чи ваші визначення базуються на сучасних тенденціях чи їх слід вважати універсальними? Дякую!
Джанго Райнхардт

3
@Django: У Паскалі процедура не може мати значення повернення, а функція повинна мати повернене значення. В деяких інших мовах термінологія може використовуватися більш вільно.
Брюс Олдермен

1
FWIW, FORTRAN мав підписки та функції з перших днів, різниця полягала в тому, що SUBROUTINE не повертає значення. Я не пам'ятаю про ALGOL, з якого походить Паскаль.
Девід Торнлі

2
@ 3p1c_d3m0n Це, безумовно, правда, що functionвиконує обидві ролі в JS, але функції JS все повертаються. Коли оператор return не має значення, це значення неявно undefined. Коли твердження про повернення відсутнє, інтерпретатор додає неявну заяву повернення. Езотерика, можливо, але це відповідає визначенню, даному тут. Саме тому var x = function() {}();є законним в JS; якби не неявна віддача, це могло б бути помилкою, як це було б у Паскалі.
напівколонка

52

Функція є те , що займає купу входів і повертає одне або кілька значень. Якщо повернені значення повністю визначаються вхідними даними, а функція не має жодних побічних ефектів (реєстрація, можливо, або викликає зміни стану поза собою), то це називається чистою функцією.

Процедура представляє собою функцію , яка не повертає значення. Зокрема, це означає, що процедура може викликати лише побічні ефекти. (Це може включати мутацію вхідного параметра!)

Метод є функцією , яка закриває над безліччю змінних, тобто замикання . Він приймає нульові або більше вхідних параметрів, має доступ до цього набору змінних і повертає нульове або більше значень. У мовах ОО цих методів додаються до об'єктів або класів.

У більшості основних мов OO ці змінні, що закриваються, називаються полями-членами або змінними екземпляра об'єкта. Метод може бути чистою функцією, нечистою функцією або процедурою.

Останнє визначення призводить до відповідності об'єкта = структура + закриття .


5
Отже, об'єкт - це сукупність змінних і сукупність закриттів над цими загальними змінними. В основному, об'єктно-орієнтовані мови завжди мали закриття і ніхто не знав? Цікавий вид! +1
Джорджіо

1
Я не вірю, що більшість методів близькі ні до чого. foo.doSomething()не є параметричним. Він має один параметр (об'єкт foo) із заданим із деяким синтаксичним цукром. Закриття могло б посилатися на свій об'єкт, не потребуючи такого параметра. Це не означає, що методи не можуть бути закритими, просто, що більшість ні, і що бути OO недостатньо для мови для підтримки закриття.
8bittree

3
foo.doSomething()закривається над fooзмінною. Будь-який виступ у програмі doSomethingможе отримати доступ fooчерез thisабо self, залежно від вашої мови. Це саме визначення "близького". Класи близькі до змінних своїх членів, тому (ігноруючи "що таке ОО"), OO є достатнім. Це досить добре відомо в літературі ...
Френк Ширар

1
Е, ні. Бачите, що мало foo.на передній частині foo.doSomething()? Ось ти передаєш doSomething()параметр. Тільки тому, що він не знаходиться між круглими дужками, не означає, що це не параметр. Метод thisабо selfвсередині є просто синтаксичним цукром для посилання на цей параметр.
8bittree

1
@FrankShearar, я б сказав, що у обчислювальних технологіях є лише два досить чіткі відмінності - дані та інструкції. Навіть це виходить у вікно у (незвичному) випадку самовиправляючого коду. В OO те, що в основному називають "методом" (або "функцією-членом"), не повинно бути ні методом, ні функцією за вашим визначенням - всі ці слова в загальному вживанні є фактично синонімами із загальним і взаємозамінним значенням. "Нечиста функція", на існування якої ви натякаєте, є просто іншим (а також найбільш довготривалим і жаргоністичним) синонімом того ж загального поняття "інструкції".
Стів

14

Брюс має хорошу відповідь . Я б додав, семантично:

  • Процедура повинна "зробити щось" аргументам або викликати інший побічний ефект (наприклад printf)
  • Функція повинна (а) відповісти на запитання про аргументи або (b) обчислити нове значення на основі аргументів
  • Метод функції повинен відповісти на запитання про стан об'єкта
  • Метод процедури повинен змінити стан об'єкта

Чудова відповідь! Лише одне крихітне доповнення: A procedure should "do something" to the arguments- або спричинить якийсь інший побічний ефект (наприклад printf).
Аллон Гуралнек

1
@Allon Зауважте, що printfповертає значення - кількість надрукованих символів - тому технічно це функція.
Sjoerd

@Sjoerd Я не згоден, що printfце цінність. Це мало специфічний побічний ефект поза сферою його виклику: а саме вводу / виводу до того, яким стандартним висновком він повинен бути. Незважаючи на те, що у Скотта це розрізнення не було явним, у функціональних функціях програмування не повинно бути побічних ефектів, і він повинен мати можливість відповідати на запитання так, ніби у вас є фактичні дані, які він повертає.
Алан

4

хороші детальні відповіді вище; коротка історія полягає в тому, що вони будуть усіма смаками підпрограм; що розуміється під кожним терміном, буде залежати від контексту мови програмування

загалом, функції повертають значення, але цього не потрібно

методи є загальними термінами OOP на даний момент

у SQL зберігаються процедури мають виходи, але зазвичай повертають лише код помилки, тоді як визначені користувачем функції повинні повертати значення (яке може бути набором результатів)

знову ж таки, точна різниця між цими термінами залежить від того, з ким ви говорите!


2

80% кваліфікації безпосередньо пов'язані з ознайомленням з номенклатурою,

95% продуктивності - це здатність визначити, що корисно на даний момент, незважаючи на терміни, які використовуються для його опису

Я дуже вважаю за краще називати їх усіма методами в c #, крім тому, коли я використовував MSSQL, у нас були sproc's, але, звичайно, зараз ми використовуємо Postgres, і вони називаються функціями.


13
83,5% усіх статистичних даних складаються на місці ;-P
Django Reinhardt

1
Маю визнати, я нервуюсь, коли чую, як хтось накидається терміном "метод" під час роботи мовою, що не входить в ООС. Здається, вона сильно корелює з набігом на неідіоматичний код.
Racheet

Я використовую "Метод" при посиланні на код C, оскільки багато програмістів ОО, з якими я маю справу, мають розумовий зрив, коли чують процедуру або функцію термінів. Для задоволення, якщо мені дуже хочеться возитися з ними, я можу замінити умови випадковим чином. Це не добре, на зразок запрошення до вас додому полтергейста ... :)
mattnz
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.