Sự khác biệt giữa chức năng của người khác là gì và một quy trình của người khác là gì?


202

Nói chung, tất cả chúng ta đều nghe về các chức năng hoặc quy trình trong ngôn ngữ lập trình. Tuy nhiên, tôi chỉ phát hiện ra rằng tôi sử dụng các thuật ngữ này gần như có thể thay thế cho nhau (điều này có lẽ rất sai).

Vì vậy, câu hỏi của tôi là:

Sự khác biệt về chức năng, mục đích và cách sử dụng của họ là gì?

Một ví dụ sẽ được đánh giá cao.



6
Tôi nghĩ SICP đã đúng. Hàm chỉ tồn tại trong toán học, và chúng đại diện cho kiến thức là gì . Các thủ tục tồn tại trong các ngôn ngữ lập trình (bao gồm cả các chức năng) và chúng đại diện cho cách hiểu biết. Hàm : sqrt (x) = y sao cho y ^ 2 = x. Thủ tục : (define (sqrt x) (newtons-method (lambda (y) (- (square y) x)) 1.0)).
mk12

Câu trả lời:


294

Một hàm trả về một giá trị và một thủ tục chỉ thực hiện các lệnh.

Hàm tên xuất phát từ toán học. Nó được sử dụng để tính toán một giá trị dựa trên đầu vào.

Một thủ tục là một tập hợp các lệnh có thể được thực hiện theo thứ tự.

Trong hầu hết các ngôn ngữ lập trình, thậm chí các hàm có thể có một bộ lệnh. Do đó, sự khác biệt chỉ là trong việc trả lại một phần giá trị.

Nhưng nếu bạn muốn giữ một chức năng sạch sẽ, (chỉ cần nhìn vào các ngôn ngữ chức năng), bạn cần đảm bảo rằng một chức năng không có tác dụng phụ.


Làm thế nào bạn có thể đảm bảo không có tác dụng phụ trong ngôn ngữ bắt buộc (java, c) hoặc ngôn ngữ khai báo (scala, lược đồ)?
orlybg

1
@orlybg, trong các ngôn ngữ khai báo, tính nhất quán đến từ việc thực hiện ngôn ngữ. Phạm vi hạn chế của họ ngăn cản họ có tác dụng phụ. Mặt khác, các ngôn ngữ bắt buộc khai thác tác dụng phụ của chúng một cách rõ ràng. Tác dụng phụ không phải lúc nào cũng xấu.
Tharindu Rusira

Tôi đang đọc hướng dẫn Ada sau ( goanna.cs.rmit.edu.au/~dale/ada/aln/8_subprograms.html ), trong đó đoạn thứ hai của trang đó bắt đầu bằng "Thủ tục trong Ada tương tự như trong Pascal Một thủ tục có thể chứa các câu lệnh return. ". Đây có phải là một lỗi trong văn bản? Hoặc nó có nghĩa là nó có thể có câu lệnh trả về nhưng không trả về bất kỳ giá trị nào?
jviotti

3
Trong pascal, các thủ tục không có câu lệnh return, chỉ có các hàm làm. Phải là một lỗi trong văn bản. Tuy nhiên, một thủ tục có thể có câu lệnh "exit", có thể đóng vai trò là câu lệnh "return" mà không có đối số, nghĩa là không có giá trị trả về.
Eric Fortier

Hàm có thể nhận đầu vào và chỉ trả về một đầu ra. thủ tục hoặc macro có thể nhận đầu vào và không trả về bất kỳ dữ liệu nào chỉ thực hiện số lượng câu lệnh. sự khác biệt chính là thủ tục không thể trả về bất kỳ loại dữ liệu.
EsmaeelE

42

Điều này phụ thuộc vào bối cảnh.

Trong các ngôn ngữ giống như Pascal, các hàm và thủ tục là các thực thể riêng biệt, khác nhau về việc chúng có hoặc không trả về giá trị. Họ cư xử khác nhau wrt. cú pháp ngôn ngữ (ví dụ: thủ tục gọi các câu lệnh biểu mẫu; bạn không thể sử dụng lệnh gọi thủ tục bên trong một biểu thức so với các lệnh gọi hàm không phải là câu lệnh, bạn phải sử dụng chúng trong các câu lệnh khác). Do đó, các lập trình viên Pascal lai tạo phân biệt giữa những người đó.

Trong các ngôn ngữ giống như C và nhiều ngôn ngữ đương đại khác, sự khác biệt này không còn nữa; trong các ngôn ngữ gõ tĩnh, các thủ tục chỉ là các hàm với kiểu trả về ngộ nghĩnh. Đây có lẽ là lý do tại sao chúng được sử dụng thay thế cho nhau.

Trong các ngôn ngữ chức năng, thường không có thứ gọi là thủ tục - mọi thứ đều là hàm.


và tài liệu của các ngôn ngữ lập trình có thể gọi các hàm và thủ tục bất cứ thứ gì nó thích, bởi vì mọi người sẽ chấp nhận bất kỳ tên nào vì nền tảng đằng sau các tên đó đã bị xóa sạch từ lâu.
Arne Babenhauserheide

18

Ví dụ trong C:

// function
int square( int n ) {
   return n * n;
}

// procedure
void display( int n ) {
   printf( "The value is %d", n );
}

Mặc dù bạn cần lưu ý rằng Tiêu chuẩn C không nói về các thủ tục, chỉ có các chức năng.


4
... Tiêu chuẩn C không nói về các thủ tục, chỉ có chức năng. Đó là bởi vì nó chỉ có chức năng. Hàm trả về không có gì là a void function. Kernighan & Ritchie Ch 1.7: "Trong C, một hàm tương đương với chương trình con hoặc hàm trong Fortran, hoặc một thủ tục hoặc hàm trong Pascal." Nói cách khác ... câu trả lời này là sai.
Mogsdad

8
Câu trả lời là không sai, và đó là một ví dụ tốt về sự khác biệt giữa các hàm và thủ tục thuần túy. K & R gọi mỗi chương trình con là "hàm" để giữ cho mọi thứ đơn giản, nhưng chương trình con có tác dụng phụ thực chất là một "thủ tục", không phải là "hàm" theo nghĩa chính tắc từ toán học. C có thể là một ngôn ngữ tốt hơn nếu nó phân biệt các chức năng thực với các thủ tục, điều này sẽ giúp phân tích tĩnh, tối ưu hóa hiệu suất và song song hóa.
Sam Watkins

12

Nói chung, một thủ tục là một chuỗi các hướng dẫn.
Một hàm có thể giống nhau, nhưng nó thường trả về một kết quả.


11

Có một chương trình con hoặc chương trình con thuật ngữ đại diện cho một đoạn mã được tham số hóa có thể được gọi từ các vị trí khác nhau.

Chức năng và thủ tục là thực hiện của những người. Thông thường các hàm trả về giá trị và thủ tục không trả về bất cứ thứ gì.


6

Sự khác biệt cơ bản

  • Hàm phải trả về một giá trị nhưng trong Thủ tục lưu trữ, nó là tùy chọn: một thủ tục có thể trả về 0 hoặc n giá trị.
  • Các hàm chỉ có thể có các tham số đầu vào cho nó, trong khi các thủ tục có thể có các tham số đầu vào / đầu ra.
  • Đối với một Hàm, bắt buộc phải lấy một tham số đầu vào, nhưng Quy trình được lưu có thể mất từ ​​0 đến n tham số đầu vào.
  • Các hàm có thể được gọi từ một thủ tục trong khi các thủ tục không thể được gọi từ một hàm.

Sự khác biệt nâng cao

  • Các ngoại lệ có thể được xử lý bằng các khối bắt thử trong Quy trình, trong khi đó, khối bắt thử có thể được sử dụng trong Hàm.
  • Chúng tôi có thể đi Quản lý giao dịch trong một thủ tục, trong khi ở Chức năng chúng tôi không thể.

Trong SQL:

  • Một thủ tục cho phép SELECTcũng như DML ( INSERT, UPDATE, DELETE) báo cáo trong đó, trong khi chức năng chỉ cho phép SELECTtuyên bố trong đó.
  • Các thủ tục không thể được sử dụng trong một SELECTcâu lệnh, trong khi Hàm có thể được nhúng trong một SELECTcâu lệnh.
  • Các thủ tục lưu sẵn không thể được sử dụng trong các câu lệnh SQL ở bất cứ đâu trong khối WHERE(hoặc a HAVINGhoặc a SELECT), trong khi Hàm có thể.
  • Các hàm trả về bảng có thể được coi là một Rowset khác. Điều này có thể được sử dụng trong một JOINkhối với các bảng khác.
  • Hàm Inline có thể được coi là các khung nhìn lấy tham số và có thể được sử dụng trong JOINcác khối và các hoạt động Rowset khác.

3
Câu trả lời này rất cụ thể về ngôn ngữ, trong khi câu hỏi là bất khả tri về ngôn ngữ. Các tuyên bố ở đây không hoàn toàn đúng trong trường hợp chung, nhưng sẽ hữu ích nếu bạn làm rõ ngôn ngữ hoặc môi trường mà bạn đang khẳng định chúng.
Mogsdad

5

Nghiêm ngặt hơn, một hàm f tuân theo thuộc tính f (x) = f (y) nếu x = y, tức là nó tính cùng một kết quả mỗi lần nó được gọi với cùng một đối số (và do đó nó không thay đổi trạng thái của hệ thống.)

Do đó, rand () hoặc print ("Hello"), v.v. không phải là chức năng mà là thủ tục. Trong khi sqrt (2.0) phải là một hàm: không có hiệu ứng có thể quan sát được hoặc thay đổi trạng thái cho dù người ta có gọi nó thường xuyên và nó luôn trả về 1,41 và một số.


3
Việc sử dụng này là không liên quan trong bối cảnh lập trình "chức năng". Xin lưu ý rằng nhiều ngôn ngữ (thường là bắt buộc) gọi chương trình con là "hàm" không yêu cầu thuộc tính này.
dmckee --- ex-moderator mèo con

1
Tôi không đề xuất rằng các ngôn ngữ lập trình yêu cầu thuộc tính này. Dù sao, người ta có thể viết các chức năng nghiêm ngặt bằng bất kỳ ngôn ngữ nào và tôi cảm thấy đó là thói quen tốt để lập trình càng nhiều càng tốt trong các chức năng sạch, sau đó dán các mảnh lại với nhau bằng một số thủ tục chính.
Ingo

4

Nếu chúng ta không biết ngôn ngữ ở đây, quy trình thường chỉ định một loạt các hành vi cần thiết để đạt được kết quả nhất định và đáng tin cậy. Đó là, một thủ tục về cơ bản là một thuật toán.

Các hàm, mặt khác, là một đoạn mã hơi độc lập trong một chương trình lớn hơn. Nói cách khác, chức năng là việc thực hiện một thủ tục.


4

Đây là một câu hỏi cũ nổi tiếng, nhưng tôi muốn chia sẻ thêm một số hiểu biết về nghiên cứu và thiết kế ngôn ngữ lập trình hiện đại.

Câu trả lời cơ bản

Theo truyền thống (theo nghĩa lập trình có cấu trúc ) và không chính thức, một thủ tục là một cấu trúc cấu trúc có thể sử dụng lại để có "đầu vào" và để làm một cái gì đó có thể lập trình được. Khi cần thực hiện một cái gì đó trong một thủ tục, bạn có thể cung cấp các đối số (thực tế) cho thủ tục trong một cuộc gọi thủ tục được mã hóa trong mã nguồn (thường là trong một loại biểu thức) và các hành động được mã hóa trong thân thủ tục (được cung cấp trong định nghĩa của thủ tục) sẽ được thực hiện với sự thay thế các đối số thành các tham số (chính thức) được sử dụng trong phần thân.

Một hàm không chỉ là một thủ tục vì các giá trị trả về cũng có thể được chỉ định là "đầu ra" trong phần thân. Các lệnh gọi hàm ít nhiều giống với các lệnh gọi thủ tục, ngoại trừ việc bạn cũng có thể sử dụng kết quả của lệnh gọi hàm, theo cú pháp (thường là biểu hiện phụ của một số biểu thức khác).

Theo truyền thống, các cuộc gọi thủ tục (chứ không phải là các cuộc gọi chức năng) được sử dụng để chỉ ra rằng không có đầu ra nào phải được quan tâm và phải có tác dụng phụ để tránh cuộc gọi là không hoạt động, do đó nhấn mạnh vào mô hình lập trình bắt buộc . Nhiều ngôn ngữ lập trình truyền thống như Pascal cung cấp cả "thủ tục" và "hàm" để phân biệt sự khác biệt có chủ ý này của các kiểu.

(Để rõ ràng, "đầu vào" và "đầu ra" được đề cập ở trên là các khái niệm đơn giản hóa dựa trên các thuộc tính cú pháp của nhiều hàm. Ngoài ra, nhiều ngôn ngữ còn hỗ trợ truyền đối số cho tham số bằng cách tham chiếu / chia sẻ, để cho phép người dùng vận chuyển thông tin được mã hóa trong các đối số trong các cuộc gọi trong khi gọi Tham số như vậy thậm chí có thể được gọi là "tham số vào / ra". Tính năng này dựa trên bản chất của các đối tượng được truyền trong các cuộc gọi, trực giao với các thuộc tính của tính năng của thủ tục / hàm.)

Tuy nhiên, nếu kết quả của một cuộc gọi hàm là không cần thiết, thì nó có thể bị bỏ qua (ít nhất là về mặt logic) và các định nghĩa hàm / các lệnh gọi hàm phải phù hợp với các định nghĩa thủ tục / các cuộc gọi thủ tục theo cách này. Các ngôn ngữ giống ALGOL như C, C ++ và Java, tất cả đều cung cấp tính năng của "hàm" theo cách này: bằng cách mã hóa loại kết quảvoid như một trường hợp đặc biệt của các hàm trông giống như các thủ tục truyền thống, không cần phải cung cấp tính năng của "thủ tục" " riêng biệt. Điều này ngăn chặn một số sự phình to trong thiết kế ngôn ngữ.

Vì SICP được đề cập, điều đáng chú ý là trong ngôn ngữ Scheme được chỉ định bởi R n RS , một thủ tục có thể hoặc không phải trả về kết quả tính toán. Đây là sự kết hợp giữa "hàm" truyền thống (trả về kết quả) và "thủ tục" (không trả về gì), về cơ bản giống với khái niệm "hàm" của nhiều ngôn ngữ giống ALGOL (và thực sự chia sẻ nhiều đảm bảo hơn như đánh giá ứng dụng của toán hạng trước cuộc gọi). Tuy nhiên, sự khác biệt thời trang cũ vẫn xảy ra ngay cả trong các tài liệu quy phạm như SRFI-96 .

Tôi không biết nhiều về lý do chính xác đằng sau sự khác biệt, nhưng như tôi đã trải nghiệm, dường như các nhà thiết kế ngôn ngữ sẽ hạnh phúc hơn nếu không có thông số kỹ thuật ngày nay. Đó là, "thủ tục" như một tính năng độc lập là không cần thiết. Các kỹ thuật như voidloại đã đủ để đánh dấu việc sử dụng trong đó các tác dụng phụ cần được nhấn mạnh. Điều này cũng tự nhiên hơn đối với người dùng có trải nghiệm về các ngôn ngữ giống như C, vốn phổ biến hơn một vài thập kỷ. Hơn nữa, nó tránh được sự bối rối trong các trường hợp như R n RS trong đó "thủ tục" thực sự là "chức năng" theo nghĩa rộng hơn.

Về lý thuyết, một hàm có thể được chỉ định với một loại đơn vị được chỉ định là loại kết quả gọi hàm để chỉ ra kết quả đó là đặc biệt. Điều này phân biệt các thủ tục truyền thống (trong đó kết quả của một cuộc gọi là không quan tâm) với những người khác. Có nhiều phong cách khác nhau trong thiết kế ngôn ngữ:

  • Như trong R n RS, chỉ cần đánh dấu các kết quả không quan tâm là giá trị "không xác định" (thuộc loại không xác định, nếu ngôn ngữ phải đề cập đến nó) và nó đủ để bị bỏ qua.
  • Chỉ định kết quả không quan tâm là giá trị của loại đơn vị chuyên dụng (ví dụ: Kernel 's#inert ) cũng làm việc.
  • Khi loại đó là một loại dưới cùng , nó có thể (hy vọng) được xác minh tĩnh và ngăn chặn được sử dụng như một loại biểu thức. Các voidloại bằng các ngôn ngữ ALGOL giống như là chính xác một ví dụ về kỹ thuật này. ISO C11 _Noreturnlà một loại tương tự nhưng tinh tế hơn trong loại này.

đọc thêm

Là khái niệm truyền thống bắt nguồn từ toán học, có rất nhiều phép thuật đen mà hầu hết mọi người không bận tâm để biết. Nói đúng ra, bạn sẽ không có khả năng làm cho mọi thứ rõ ràng theo sách toán của bạn. Sách CS cũng có thể không cung cấp nhiều trợ giúp.

Liên quan đến ngôn ngữ lập trình, có một số lưu ý:

  • Các hàm trong các nhánh khác nhau của toán học không phải lúc nào cũng được định nghĩa có cùng ý nghĩa. Các hàm trong các mô hình lập trình khác nhau cũng có thể khá khác nhau (thậm chí đôi khi các cú pháp của hàm gọi trông giống nhau). Đôi khi những lý do để gây ra sự khác biệt là như nhau, nhưng đôi khi chúng không phải là.
    • Đây là thành ngữ để mô hình tính toán bởi các chức năng toán học và sau đó thực hiện các tiềm ẩn tính toán bằng các ngôn ngữ lập trình. Hãy cẩn thận để tránh ánh xạ chúng thành một trừ khi bạn biết những gì đang được nói đến.
  • Đừng nhầm lẫn mô hình với thực thể được mô hình hóa.
    • Cái sau chỉ là một trong những thực hiện cho cái trước. Có thể có nhiều hơn một sự lựa chọn, tùy thuộc vào bối cảnh (ví dụ, các nhánh toán học quan tâm).
    • Cụ thể, ít nhiều cũng vô lý tương tự khi coi "các chức năng" là "ánh xạ" hoặc các tập hợp con của các sản phẩm của Cartesian muốn coi các số tự nhiên là mã hóa Von-Neumann của các số thứ tự (trông giống như một bó {{{}}, {}}...) bên cạnh một số bối cảnh hạn chế .
  • Về mặt toán học, các hàm có thể là một phần hoặc toàn bộ . Các ngôn ngữ lập trình khác nhau có cách xử lý khác nhau ở đây.
    • Một số ngôn ngữ chức năng có thể tôn vinh toàn bộ các hàm để đảm bảo tính toán trong các lệnh gọi hàm luôn kết thúc trong các bước hữu hạn. Tuy nhiên, điều này về cơ bản không phải là Turing-Complete, do đó tính biểu cảm tính toán yếu hơn và không được thấy nhiều trong các ngôn ngữ có mục đích chung bên cạnh ngữ nghĩa của việc đánh máy (dự kiến ​​là toàn bộ).
    • Nếu sự khác biệt giữa các thủ tục và chức năng là đáng kể, liệu có nên có "tổng thủ tục" không? Hừm ...
  • Các cấu trúc tương tự như các hàm trong phép tính được sử dụng để mô hình hóa tính toán chungngữ nghĩa của các ngôn ngữ lập trình (ví dụ trừu tượng lambda trong phép tính lambda ) có thể có các chiến lược đánh giá khác nhau trên toán hạng.
    • Theo truyền thống, việc giảm các phép tính thuần túy cũng như các đánh giá biểu thức trong các ngôn ngữ chức năng thuần túy , không có tác dụng phụ làm thay đổi kết quả tính toán. Kết quả là, các toán hạng không bắt buộc phải được đánh giá trước phần thân của các cấu trúc giống như hàm (vì bất biến để định nghĩa "cùng kết quả" được giữ bởi các thuộc tính như β - tương đương được đảm bảo bởi thuộc tính Church-Rosser ).
    • Tuy nhiên, nhiều ngôn ngữ lập trình có thể có tác dụng phụ trong quá trình đánh giá biểu thức. Điều đó có nghĩa là, các chiến lược đánh giá nghiêm ngặt như đánh giá ứng dụng không giống với các đánh giá không nghiêm ngặt như gọi theo nhu cầu . Điều này rất có ý nghĩa, bởi vì không có sự phân biệt, không cần phân biệt các hàm giống như hàm (nghĩa là được sử dụng với các đối số) từ các hàm (truyền thống). Nhưng tùy thuộc vào hương vị của các lý thuyết, đây vẫn có thể là một tạo tác. Điều đó nói rằng, theo nghĩa rộng hơn, các macro giống như chức năng (đặc biệt là vệ sinh ) các hàm toán học với một số hạn chế không cần thiết (giai đoạn cú pháp). Nếu không có giới hạn, có thể coi các macro giống như hàm (hạng nhất) là thủ tục ...
    • Đối với độc giả quan tâm đến chủ đề này, hãy xem xét một số trừu tượng hiện đại .
  • Các thủ tục thường được xem là nằm ngoài phạm vi của toán học truyền thống. Tuy nhiên, khi tính toán mô hình hóa ngữ nghĩa tính toán và ngôn ngữ lập trình, cũng như các thiết kế ngôn ngữ lập trình đương đại, có thể có khá nhiều khái niệm liên quan chia sẻ bản chất "có thể gọi được". Một số trong số chúng được sử dụng để thực hiện / mở rộng / thay thế các thủ tục / chức năng. Thậm chí còn có sự phân biệt tinh tế hơn.

3

Trong hầu hết các bối cảnh: một hàm trả về một giá trị, trong khi một thủ tục thì không. Cả hai đều là những đoạn mã được nhóm lại với nhau để làm điều tương tự.

Trong ngữ cảnh lập trình chức năng (nơi tất cả các hàm trả về giá trị), một hàm là một đối tượng trừu tượng:

f(x)=(1+x)
g(x)=.5*(2+x/2)

Ở đây, f là hàm tương tự như g, nhưng là một thủ tục khác.


3

Quy trình bên trong chúng ta có thể sử dụng các câu lệnh DML (Chèn / Cập nhật / Xóa), nhưng chức năng Bên trong chúng ta không thể sử dụng các câu lệnh DML.

Quy trình có thể có cả tham số đầu vào \ đầu ra, nhưng Hàm chỉ có thể có tham số đầu vào.

Chúng tôi có thể sử dụng Khối Thử bắt trong Quy trình được lưu trữ, nhưng trong Chức năng Chúng tôi không thể sử dụng khối Thử bắt.

Chúng tôi không thể sử dụng Thủ tục lưu trữ trong câu lệnh Chọn, nhưng trong chức năng Chúng tôi có thể sử dụng trong câu lệnh Chọn.

Thủ tục lưu trữ có thể trả về 0 hoặc n giá trị (tối đa 1024), nhưng Hàm chỉ có thể trả về 1 giá trị bắt buộc.

Thủ tục lưu trữ không thể được gọi từ Hàm, nhưng Chúng ta có thể gọi hàm từ Thủ tục được lưu trữ.

Chúng tôi có thể sử dụng giao dịch trong Thủ tục lưu trữ, nhưng trong chức năng chúng tôi không thể sử dụng giao dịch.

Chúng ta không thể sử dụng Thủ tục lưu trữ trong câu lệnh Sql ở bất cứ đâu trong phần Where / Have / select, nhưng trong chức năng chúng ta có thể sử dụng.

Chúng tôi không thể tham gia Thủ tục lưu trữ, nhưng chúng tôi có thể tham gia chức năng.

để biết thêm .. bấm vào đây ... http://dotnet-developers-cafe.blogspot.in/2013/08/difference-b between-stored -procedure-and.html


2
Câu trả lời này rất cụ thể về ngôn ngữ, trong khi câu hỏi là bất khả tri về ngôn ngữ. Các tuyên bố ở đây không hoàn toàn đúng trong trường hợp chung, nhưng sẽ hữu ích nếu bạn làm rõ ngôn ngữ hoặc môi trường mà bạn đang khẳng định chúng.
Mogsdad

Câu trả lời này là hoàn toàn không chính xác cho phần lớn các ngôn ngữ lập trình. Các thủ tục chỉ có các tham số đầu vào và các chức năng có cả đầu vào và đầu ra.
AStopher

2

Một hàm trả về một giá trị và một thủ tục chỉ thực hiện các lệnh.

Hàm tên xuất phát từ toán học. Nó được sử dụng để tính toán một giá trị dựa trên đầu vào.

Một thủ tục là một tập hợp các lệnh có thể được thực hiện theo thứ tự.

Trong hầu hết các ngôn ngữ lập trình, thậm chí các hàm có thể có một bộ lệnh. Do đó, sự khác biệt chỉ là trong việc trả lại một phần giá trị.

Nhưng nếu bạn muốn giữ một chức năng sạch sẽ, (chỉ cần nhìn vào các ngôn ngữ chức năng), bạn cần đảm bảo rằng một chức năng không có tác dụng phụ.


1

Hàm có thể được sử dụng trong câu lệnh sql trong khi thủ tục không thể được sử dụng trong câu lệnh sql.

Các câu lệnh Chèn, Cập nhật và Tạo không thể được bao gồm trong hàm nhưng một thủ tục có thể có các câu lệnh này.

Thủ tục hỗ trợ giao dịch nhưng chức năng không hỗ trợ giao dịch.

Hàm phải trả về một và chỉ một giá trị (một giá trị khác có thể được trả về bởi biến OUT) nhưng thủ tục trả về nhiều bộ dữ liệu và giá trị trả về.

Kế hoạch thực hiện của cả hai chức năng và thủ tục được lưu trữ, do đó hiệu suất là như nhau trong cả hai trường hợp.


1

Tôi phản đối với một cái gì đó tôi liên tục thấy lặp đi lặp lại trong hầu hết các câu trả lời này, rằng điều làm cho hàm trở thành hàm là nó trả về một giá trị.

Hàm không chỉ là bất kỳ phương thức cũ nào trả về giá trị. Không phải như vậy: Để một phương thức là một hàm thực, nó phải trả về cùng một giá trị luôn được cung cấp một đầu vào cụ thể. Một ví dụ về phương thức không phải là hàm làrandom phương thức trong hầu hết các ngôn ngữ, bởi vì mặc dù nó trả về một giá trị nhưng giá trị không phải lúc nào cũng giống nhau.

Do đó, một chức năng gần giống với bản đồ (ví dụ: x -> x'đối với chức năng một chiều). Đây là một sự khác biệt rất quan trọng giữa các phương thức và hàm thông thường bởi vì khi xử lý các hàm thực, thời gian và thứ tự chúng được đánh giá sẽ không bao giờ quan trọng vì điều này không phải lúc nào cũng đúng với các hàm không.

Đây là một ví dụ khác về một phương thức không phải là một hàm nhưng nếu không vẫn sẽ trả về một giá trị.

// The following is pseudo code:
g(x) = {
  if (morning()) {
     g = 2 * x;
  }
  else {
   g = x;
  }
  return g;
}

Tôi tiếp tục phản đối quan niệm rằng các thủ tục không trả về giá trị. Một thủ tục chỉ là một cách cụ thể để nói về một chức năng hoặc phương thức. Vì vậy, điều đó có nghĩa là nếu phương thức cơ bản mà thủ tục của bạn xác định hoặc thực hiện trả về một giá trị thì hãy đoán xem thủ tục đó trả về giá trị gì. Lấy ví dụ đoạn trích sau từ SICP :

// We can immediately translate this definition into a recursive procedure 
// for computing Fibonacci numbers:

(define (fib n)
  (cond ((= n 0) 0)
        ((= n 1) 1)
        (else (+ (fib (- n 1))
                 (fib (- n 2))))))

Bạn đã nghe nói về các thủ tục đệ quy gần đây? Họ đang nói về một hàm đệ quy (một hàm thực) và nó trả về một giá trị và họ đang sử dụng từ "thủ tục". Vì vậy, sự khác biệt là gì?

Một cách nghĩ khác về một chức năng (bên cạnh ý nghĩa được đề cập ở trên) là một đại diện trừu tượng của một lý tưởng như chữ số 1. Một thủ tục là thực hiện thực tế điều đó. Cá nhân tôi nghĩ rằng chúng có thể thay thế cho nhau.

(Lưu ý, nếu bạn đọc chương đó từ liên kết tôi cung cấp, bạn có thể thấy rằng một khái niệm khó nắm bắt hơn không phải là sự khác biệt giữa hàm và thủ tục, mà là quy trình và thủ tục. Bạn có biết rằng thủ tục đệ quy có thể có một quy trình đệ quy quá trình lặp lại?)

Một tương tự cho các thủ tục là công thức nấu ăn. Ví dụ; giả sử bạn có một máy gọi là make-piesmáy này có thành phần (fruit, milk, flower, eggs, sugar, heat)và máy này trả về a pie.

Một đại diện của máy này có thể trông giống như

make-pies (fruit, milk, flower, eggs, sugar, heat) = {
   return (heat (add fruit (mix eggs flower milk)))
}

Tất nhiên đó không phải là cách duy nhất để làm một chiếc bánh.

Trong trường hợp này chúng ta có thể thấy rằng:

A       function     is to a     machine
as a    procedure    is to a     recipe
as      attributes   are to      ingredients
as      output       is to       product

Sự tương tự đó là ổn nhưng nó bị hỏng khi bạn tính đến việc khi bạn làm việc với một chương trình máy tính, mọi thứ đều là một sự trừu tượng. Vì vậy, không giống như trong trường hợp của một công thức cho một máy, chúng tôi đang so sánh hai thứ mà bản thân nó trừu tượng; Hai điều có thể giống nhau. Và tôi cho rằng chúng (cho tất cả các mục đích và mục đích) giống nhau.


2
Một hàm luôn trả về cùng một giá trị cho các đối số đã cho đôi khi được gọi là "hàm thuần túy". Trong hầu hết các ngôn ngữ phân biệt giữa các thủ tục và hàm, các hàm không bắt buộc phải thuần túy và thuật ngữ "hàm" được sử dụng chính xác để chỉ các chương trình con có thể có tác dụng phụ và có thể trả về các kết quả khác nhau cho các cuộc gọi liên tiếp với cùng một đối số. (Và trong các ngôn ngữ giống như C, ngay cả các chương trình con không trả về giá trị cũng được gọi đúng là "hàm".)
Keith Thompson

Đồng ý, đó là lý do tại sao tôi kết thúc vịnh nói những lời có thể hoán đổi cho nhau.
dkinzer

1
Có, nhưng bạn bắt đầu bằng cách nói rằng "Một hàm không chỉ là bất kỳ phương thức cũ nào trả về một giá trị", trong khi trong nhiều ngôn ngữ, đó chính xác là một hàm.
Keith Thompson

0

Trong ngữ cảnh của db : Thủ tục lưu trữ là kế hoạch thực hiện được biên dịch trước trong khi các hàm không có.


0

Về mặt С # / Java, hàm là khối mã, trả về giá trị cụ thể, nhưng thủ tục là khối mã trả về void (không có gì). Trong C # / Java cả hàm và thủ tục thường được gọi là phương thức .

    //This is a function
    public DateTime GetCurrentDate()
    {
        return DateTime.Now.Date;
    }

    //This is a procedure(always return void)
    public void LogMessage()
    {
        Console.WriteLine("Just an example message.");
    }

-3

Quy trình: 1.Bài tập là tập hợp các câu lệnh xác định các tính toán được tham số hóa. 2. Cung cấp không thể trả về giá trị.

3. Cung cấp không thể được gọi từ chức năng.

Các hàm 1. Các hàm tương tự về mặt cấu trúc nhưng được mô hình hóa về các hàm toán học. 2.Nó có thể trả về giá trị 3. Chức năng có thể được gọi từ các thủ tục.


3. Cung cấp không thể được gọi từ chức năng. Trong ngôn ngữ này là sự thật? Không ai mà tôi có kinh nghiệm trong việc hạn chế này.
Mogsdad

Đúng rồi. Nếu bạn gọi một thủ tục từ một hàm, thì đó không phải là một hàm. Đối với những gì ngôn ngữ thực thi điều này, đó là một câu hỏi hay, mà tôi không biết câu trả lời. Có thể là một chức năng, nhưng ngay cả khi đó tôi không chắc chắn: danh sách thuần túy là chức năng (không có tập hợp: không có tác dụng phụ), nhưng vì nó có lambdas nên có thể thực hiện tập hợp. Bạn có thể viết một trình biên dịch thực thi không sử dụng tập hợp không, nó sẽ phải phát hiện tất cả các cài đặt của nó. Bạn có thể loại bỏ lambdas khỏi ngôn ngữ, nhưng điều đó sẽ tồi tệ hơn.
ctrl-alt-delor 13/03/2016

Ồ tôi chỉ nghĩ về một ngôn ngữ C ++: một phương thức const không thể gọi một phương thức không phải là const (mặc dù bạn sẽ cần kiểm tra trình biên dịch chính xác và không cố gắng khắc phục nó.)
ctrl-alt-delor

-7

Các thủ tục và hàm đều là chương trình con, điểm khác biệt duy nhất giữa chúng là một thủ tục trả về nhiều giá trị (hoặc ít nhất có thể làm) trong khi một hàm chỉ có thể trả về một giá trị (đây là lý do tại sao ký hiệu hàm được sử dụng trong toán học vì thường chỉ tìm thấy một giá trị tại một thời điểm nhất định) mặc dù một số ngôn ngữ lập trình không tuân theo các quy tắc này, đây là định nghĩa thực sự của chúng


À, không. Một thủ tục không có returngì. Bạn đang nói về tác dụng phụ, có thể xảy ra với cả hai (nếu được ngôn ngữ cho phép).
Mogsdad

Một thủ tục có thể trả về bất kỳ số lượng giá trị nào, số tiền đó có thể bằng 0
user2766296 14/2/2016

Một tác dụng phụ sẽ là nếu một mảng có một mảng và truyền nó vào một hàm hoặc thủ tục tìm thấy giá trị lớn nhất, mảng sẽ được truyền bằng tham chiếu và sau khi thường trình con chạy mảng được sắp xếp, thực tế là nó được sắp xếp là một hiệu ứng phụ, giá trị được trả về là giá trị lớn nhất trong mảng
user2766296 14/2/2016

Tôi thích câu trả lời này, và cũng thích những câu hỏi với một số downvote bởi vì theo một cách nào đó, điều đó đúng, vì vậy, nghịch lý là, để làm cho nó rất phổ biến trong SO tôi sẽ cho nó một downvote. Một thủ tục được lưu trữ trong SQL Server trả về một tập kết quả (cái mà bạn gọi là "nhiều giá trị") trong khi một hàm chỉ có thể trả về một giá trị (không chính xác lắm vì bạn cũng có thể tạo Hàm có giá trị bảng).
Ivanzinho
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.