Metoda a funkcja a procedura

107

Proste pytanie, ale często słyszę te trzy terminy zdefiniowane z taką zaciekłością, które z biegiem lat były dla mnie różne.

Jakie są „prawidłowe” definicje „procedur”, „metod”, „funkcji”, „podprogramów” itp.?

Django Reinhardt
źródło
4
rezygnujecie z „rutyny”
mefisto
1
@teresko: Myślę, że „podprogram” jest bardziej powszechny.
mk12

Odpowiedzi:

108

Idę tutaj z inną odpowiedzią: praktycznie nie ma żadnej różnicy , z niewielkim wyjątkiem, że „metoda” zwykle odnosi się do podprogramu powiązanego z obiektem w językach OO.

Terminy „procedura, funkcja, podprogram, podprogram i metoda” naprawdę oznaczają to samo: podprogram, który można wywołać w większym programie. Ale trudno jest znaleźć definicję, która przechwytuje wszystkie warianty użycia tych terminów, ponieważ nie są one stosowane konsekwentnie we wszystkich językach programowania lub paradygmatach.

Można powiedzieć, że funkcja zwraca wartość. Cóż, następująca funkcja C nie zwraca wartości:

void f() { return; }

... ale wątpię, byś znalazł kogoś, kto nazwałby to procedurą.

Jasne, w Pascalu procedury nie zwracają wartości, a funkcje zwracają wartości, ale jest to jedynie odzwierciedlenie tego, jak zaprojektowano Pascala. W Fortranie funkcja zwraca wartość, a podprogram zwraca wiele wartości. Jednak tak naprawdę nic nie pozwala nam na opracowanie „uniwersalnej” definicji tych terminów.

W rzeczywistości termin „programowanie proceduralne” odnosi się do całej klasy języków, w tym C, Fortran i Pascal, z których tylko jeden faktycznie używa terminu „procedura”, aby cokolwiek znaczyć.

Więc nic z tego nie jest spójne. Jedynym wyjątkiem jest prawdopodobnie „metoda”, która wydaje się być stosowana prawie całkowicie w językach OO, odnosząc się do funkcji powiązanej z obiektem. Chociaż nawet to nie zawsze jest spójne. Na przykład C ++ zwykle używa terminu „funkcja członka” zamiast metody (nawet jeśli termin „metoda” wkradł się do języka C ++ wśród programistów).

Chodzi o to, że nic z tego nie jest naprawdę spójne. Po prostu odzwierciedla terminologię stosowaną przez wszystkie języki, które są w tym czasie modne.

Charles Salvia
źródło
Dokładnie tak myślałem, że odpowiedź brzmi. (Powinienem dodać „podprogram” jako kolejny wariant z perspektywy czasu.) Czy mogę zapytać: dlaczego nie znalazłbyś nikogo, kto nazwałby tę funkcję C „Procedurą”? Ponieważ jest to technicznie niepoprawne lub ponieważ termin „procedura” jest obecnie nieaktualny?
Django Reinhardt
7
Programiści C używają terminu „funkcja” po prostu dlatego, że projektanci C używali tego terminu.
Charles Salvia,
15
Nie wylewajmy dziecka z kąpielą. To, że terminologia nie jest używana z pełną spójnością, nie oznacza, że ​​różne terminy nie mają różnych znaczeń. Definicje Bruce'a i Franka są powszechnie uznawane, a nie idiosynkratyczne. Fakt, że znaczenia nie są uniwersalne, jest ważny, ale nie usprawiedliwia skoku do „praktycznie mówiąc, naprawdę nie ma różnicy”. (@Django)
LarsH
9
Rodzaj dualny do C ++, który nazywa metody „funkcjami składowymi”, funkcje wywołania Java i C # „metodami statycznymi”.
Jörg W Mittag
2
Odpowiedź Bruce'a jest zdecydowanie tą, na którą powinieneś pójść, jeśli dopiero zaczynasz programować. Jego definicje będą absolutnie poprawne, 99% czasu. Ale szukałem odpowiedzi technicznej / teoretycznej. Czasami nowi programiści znają tylko swoją własną domenę i nalegają, aby tylko tyle było. W rzeczywistości dziś pracują programiści, którzy nadal używają starszych języków i którzy nie są „źli” w używaniu różnych definicji. Właśnie to najbardziej mnie interesowało.
Django Reinhardt,
67

Funkcja zwraca wartość, ale procedura nie.

Metoda jest podobna do funkcji, ale wewnętrznego części klasy. Termin metoda jest stosowany prawie wyłącznie w programowaniu obiektowym.

Bruce Alderman
źródło
8
Niezupełnie wewnętrzny. Metoda to dowolna funkcja lub procedura, która jest częścią klasy.
Scott Whitlock,
8
Zatem „procedura składowana” w SQL nie zwraca żadnych wartości? Co z „procedurą” w czymś takim jak Pascal? Czy twoje definicje są oparte na aktualnych trendach, czy powinny być uważane za definicje uniwersalne? Dzięki!
Django Reinhardt
3
@Django: W Pascalu procedura nie może mieć wartości zwracanej, a funkcja musi mieć wartość zwracaną. W niektórych innych językach terminologia może być stosowana luźniej.
Bruce Alderman,
1
FWIW, FORTRAN miał SUBROUTYNY i FUNKCJE od pierwszych dni, z tą różnicą, że SUBROUTYNA nie zwróciła wartości. Nie pamiętam o ALGOLU, z którego pochodzi Pascal.
David Thornley,
2
@ 3p1c_d3m0n Z pewnością jest prawdą, że functionspełnia obie role w JS, ale wszystkie funkcje JS powracają. Jeśli instrukcja return nie ma wartości, wartość ta jest niejawna undefined. Gdy instrukcja return jest nieobecna, interpreter dodaje niejawną instrukcję return. Może ezoteryczny, ale jest zgodny z podaną tutaj definicją. Dlatego var x = function() {}();jest legalne w JS; gdyby nie zwroty niejawne, musiałby to być błąd, tak jak w Pascalu.
Semicolon,
52

Funkcja jest coś, co zajmuje kilka wejść i zwraca jeden lub więcej wartości. Jeśli zwracane wartości są całkowicie określane przez dane wejściowe, a funkcja nie ma żadnych skutków ubocznych (być może rejestrowanie lub powodowanie zmian stanu poza sobą), wówczas jest to nazywane funkcją czystą.

Procedura jest funkcją, która nie zwraca wartości. W szczególności oznacza to, że procedura może powodować tylko skutki uboczne. (Może to obejmować mutację parametru wejściowego!)

Metoda jest funkcją, która zamyka się w zbiorze zmiennych, to jest zamknięcie . Pobiera zero lub więcej parametrów wejściowych, ma dostęp do tego zestawu zmiennych i zwraca zero lub więcej wartości. W językach OO metody te są dołączane do obiektów lub klas.

W większości popularnych języków programowania zmienne zamknięte nazywane są polami składowymi lub zmiennymi instancji obiektu. Metoda może być czystą funkcją, nieczystą funkcją lub procedurą.

Ta ostatnia definicja prowadzi do korespondencji obiekt = struktura + zamknięcia .

Frank Shearar
źródło
5
Zatem obiekt jest zbiorem zmiennych i zbiorem zamknięć nad tymi wspólnymi zmiennymi. Zasadniczo języki zorientowane obiektowo zawsze miały zamknięcia i nikt nie wiedział? Ciekawy widok! +1
Giorgio
1
Nie wierzę, że większość metod jest do niczego zbliżona. foo.doSomething()nie jest bez parametrów. Ma jeden parametr (obiekt foo) z danym cukrem składniowym. Zamknięcie byłoby w stanie odwoływać się do jego obiektu bez potrzeby posiadania takiego parametru. Nie oznacza to, że metody nie mogą być zamknięciami, po prostu większość z nich nie jest, a bycie OO nie wystarcza, aby język obsługiwał zamknięcia.
8bittree,
3
foo.doSomething()zamyka foozmienną. Każde oświadczenie w doSomethingmoże uzyskać dostęp fooza pośrednictwem thislub self, w zależności od języka. To jest właśnie definicja „blisko”. Klasy zamykają swoje zmienne składowe, dlatego (ignorując „co to jest OO”), OO jest wystarczające. Jest to dość dobrze znane w literaturze ...
Frank Shearar
1
Eee nie. Widzisz to trochę foo.z przodu foo.doSomething()? To jest przekazanie doSomething()parametru. To, że nie znajduje się pomiędzy nawiasami, nie oznacza, że ​​nie jest to parametr. Metoda thislub selfwewnątrz metody jest po prostu cukrem syntaktycznym służącym do odwoływania się do tego parametru.
8bittree,
1
@FrankShearar, powiedziałbym, że istnieją tylko dwa dość wyraźne rozróżnienia w informatyce - dane i instrukcje. Nawet to wychodzi poza okno w (nietypowym) przypadku kodu modyfikującego się. W OO to, co jest ogólnie określane jako „metoda” (lub „funkcja składowa”), nie musi być ani metodą ani funkcją z definicji - wszystkie te słowa w powszechnym użyciu są faktycznie synonimami o ogólnym i wymiennym znaczeniu. „Nieczysta funkcja”, o której istnieniu się wspomina, jest po prostu kolejnym (a także najbardziej rozwlekłym i żargonistycznym) synonimem tej samej ogólnej koncepcji „instrukcji”.
Steve,
14

Bruce ma dobrą odpowiedź . Dodałbym semantycznie:

  • Procedura powinna „zrobić coś” z argumentami lub spowodować inny efekt uboczny (np. printf)
  • Funkcja powinna (a) odpowiedzieć na pytanie dotyczące argumentów lub (b) obliczyć nową wartość na podstawie argumentów
  • Metoda funkcyjna powinna odpowiedzieć na pytanie o stan obiektu
  • Metoda procedury powinna zmienić stan obiektu
Scott Whitlock
źródło
Świetna odpowiedź! Tylko jeden malutki dodatek: A procedure should "do something" to the arguments- lub wywołać inny efekt uboczny (np printf.).
Allon Guralnek
1
@ Allon Zwróć uwagę, że printfzwraca wartość - liczbę wydrukowanych znaków - więc jest to technicznie funkcja.
Sjoerd
@ Sjoerd Nie zgadzam się, że printfto wartość. Miał specyficzny efekt uboczny poza zakresem wywoływania: mianowicie we / wy niezależnie od standardowego wyjścia, jakie powinno być. Chociaż Scott nie wyraził tego rozróżnienia, w funkcyjnym programowaniu funkcje nie powinny mieć skutków ubocznych i powinny być w stanie odpowiadać na pytania, jakbyś miał rzeczywiste dane, które zwraca.
Alan
4

dobre szczegółowe odpowiedzi powyżej; opowiadanie jest takie, że wszystkie smaki podprogramów; znaczenie każdego terminu będzie się różnić w zależności od kontekstu języka programowania

generalnie funkcje zwracają wartość, ale nie muszą

metody to ogólne warunki OOP chwili obecnej

w SQL procedury składowane mają dane wyjściowe, ale zwykle zwracają tylko kod błędu, podczas gdy funkcje zdefiniowane przez użytkownika muszą zwracać wartość (która może być zestawem wyników)

ponownie, dokładna różnica między tymi warunkami zależy od tego, z kim rozmawiasz!

Steven A. Lowe
źródło
2

80% biegłości jest bezpośrednio związane ze znajomością nomenklatury,

95% wydajności to zdolność do zidentyfikowania tego, co jest obecnie przydatne, pomimo terminów użytych do jej opisania

Raczej wolę nazywać je wszystkimi metodami w języku c #, z wyjątkiem sytuacji, gdy użyłem MSSQL, mieliśmy sproc, ale oczywiście teraz używamy Postgres i są one nazywane funkcjami.

MvcCmsJon
źródło
13
83,5% wszystkich statystyk jest sporządzanych na miejscu ;-P
Django Reinhardt
1
Muszę przyznać, że denerwuję się, gdy słyszę, jak ktoś rzuca się wokół terminu „metoda” podczas pracy w języku innym niż język OO. Wydaje się, że jest silnie skorelowane z uruchamianiem kodu nieidiomatycznego.
Racheet
Używam „metody”, odnosząc się do kodu C, ponieważ wielu programistów OO, z którymi mam do czynienia, ma załamanie psychiczne po usłyszeniu procedury lub funkcji warunków. Dla zabawy, jeśli naprawdę chcę z nimi zadzierać, mogę losowo zamieniać warunki. To nie jest dobre, jakby zaprosić poltergeist do ciebie do domu ... :)
mattnz