Một tác dụng phụ là gì?


87

Tôi chưa hiểu rõ khái niệm về tác dụng phụ.

  • Tác dụng phụ trong lập trình là gì?
  • Có phải nó phụ thuộc ngôn ngữ lập trình?
  • Có một điều như tác dụng phụ bên ngoài và bên trong?

Vui lòng cho một số ví dụ về nguyên nhân tạo ra tác dụng phụ.


7
Âm thanh rất giống bài tập về nhà.
gnasher729

3
@ gnasher729 người quan tâm đây là TREMENDOUSLY hữu ích :)
Charlie Parker

Câu trả lời:


108

Một tác dụng phụ chỉ đơn giản là sửa đổi một số loại trạng thái - ví dụ:

  • Thay đổi giá trị của một biến;
  • Ghi một số dữ liệu vào đĩa;
  • Kích hoạt hoặc vô hiệu hóa một nút trong Giao diện người dùng.

Trái với những gì một số người dường như đang nói:

  • Một tác dụng phụ không phải bị ẩn hoặc bất ngờ (có thể, nhưng điều đó không liên quan gì đến định nghĩa vì nó áp dụng cho khoa học máy tính);

  • Một tác dụng phụ không có gì để làm với idempotency. Hàm idempotent có thể có tác dụng phụ và hàm không idempotent có thể không có tác dụng phụ (chẳng hạn như lấy ngày và giờ hệ thống hiện tại).

Nó thực sự rất đơn giản. Tác dụng phụ = thay đổi một cái gì đó ở đâu đó.

PS Như nhà bình luận benjol chỉ ra, một số người có thể nhầm lẫn giữa định nghĩa về tác dụng phụ với định nghĩa của hàm thuần túy , đó là một hàm (a) idempotent và (b) không có tác dụng phụ. Một cái không bao hàm cái khác trong khoa học máy tính nói chung, nhưng các ngôn ngữ lập trình chức năng thường sẽ có xu hướng thực thi cả hai ràng buộc.


38
Cụm từ "tác dụng phụ" làm cho nó có vẻ như một cái gì đó khác đang được thay đổi khác với những gì đã được dự định. Trong y học, một loại thuốc sẽ có tác dụng chính là giảm đau, và đôi khi là tác dụng phụ gây chảy máu mũi, chóng mặt, v.v ... mục đích của thuốc không phải là gây chảy máu mũi mà đôi khi xảy ra như một kết quả phụ ngoài ý muốn .
Thất vọngWithFormsDesigner

15
@Frustrated: +1. Bất cứ khi nào tôi thấy thuật ngữ đó, tôi không thể không tự hỏi liệu nó không được chọn bởi những người ủng hộ FP để tạo ra chính xác ý nghĩa độc ác tinh tế đó.
Mason Wheeler

6
@Mason Wheeler. Nó tồn tại rất lâu trước khi FP. Và nó không phải là một ý nghĩa nham hiểm tinh tế. Đó là tà ác và luôn luôn như vậy. Trong 3 thập kỷ tôi đã mã hóa, tuyên bố "chuyển nhượng tiền điện tử" - tác dụng phụ - đã gây phiền hà cho mọi người. Một tuyên bố chuyển nhượng cũ đơn giản là dễ dàng hơn nhiều để đối phó với.
S.Lott

7
@Mason Wheeler: Trong C ++a.. Không giống như sự phân công. b = ++a;có hai tác dụng phụ. Một điều hiển nhiên và sự phân công của tiền điện tử a. Đó là loại điều mà một tác dụng phụ mà (với một số) là mong muốn. Nhưng đã được gọi là một tác dụng phụ cho toàn bộ sự nghiệp của tôi để làm cho nó không tinh tế.
S.Lott

5
@Zachary, xin vui lòng xem điểm đạn cuối cùng trong câu trả lời của tôi. Những gì bạn đang đề cập đến là hành vi bình thường (hoặc thiếu nó). Điều đó không cho bạn biết bất cứ điều gì về tác dụng phụ. Kiểm tra đồng hồ hệ thống không phải là một tác dụng phụ; trong thực tế, bất kỳ chức năng hoặc phương thức nào có tiền tố từ "get" là một chức năng mà bạn mong muốn một cách hợp lý để không có bất kỳ tác dụng phụ nào.
Aaronaught

36

Bất kỳ hoạt động nào sửa đổi trạng thái của máy tính hoặc tương tác với thế giới bên ngoài được cho là có tác dụng phụ. Xem Wikipedia về Tác dụng phụ .

Ví dụ, chức năng này không có tác dụng phụ. Kết quả của nó chỉ phụ thuộc vào các đối số đầu vào của nó và không có gì về trạng thái của chương trình hoặc môi trường của nó thay đổi khi được gọi:

int square(int x) { return x * x; }

Ngược lại, việc gọi các chức năng này sẽ cung cấp cho bạn các kết quả khác nhau tùy theo thứ tự bạn gọi chúng, bởi vì chúng thay đổi điều gì đó về trạng thái của máy tính:

int n = 0;
int next_n() { return n++; }
void set_n(int newN) { n = newN; }      

Hàm này có tác dụng phụ là ghi dữ liệu vào đầu ra. Bạn không gọi hàm vì bạn muốn giá trị trả về của nó; bạn gọi nó bởi vì bạn muốn hiệu ứng của nó đối với "thế giới bên ngoài":

int Write(const char* s) { return printf("Output: %s\n", s); }

1
Đây là một định nghĩa tốt, nhưng tôi không điên về sự trau chuốt - giống như trong câu trả lời của Thorbjørn, một phần của nó dường như đang làm lẫn lộn vấn đề tác dụng phụ với chức năng của idempotent; như Writeví dụ của bạn chứng minh, có tác dụng phụ không có nghĩa là hàm bao giờ thay đổi đầu ra của nó đối với đầu vào của nó, hoặc thậm chí đầu ra của nó phụ thuộc vào đầu vào.
Aaronaught

6
Đó không phải là về việc bình thường. Thực tế là nó tạo ra đầu ra có nghĩa là nó có tác dụng phụ.
Kristopher Johnson

Trong một số hệ thống, việc gọi square(x)có thể khiến mô-đun nơi hàm được xác định được tải từ đĩa. Điều này có nên được coi là tác dụng phụ? Rốt cuộc, người đàn ông mà cuộc gọi (đầu tiên) này mất nhiều thời gian bất ngờ, việc sử dụng RAM tăng lên, v.v.
Hagen von Eitzen

1
@HagenvonEitzen Mọi thao tác thực sự thay đổi trạng thái của máy tính (thanh ghi CPU, bộ nhớ, mức tiêu thụ điện, nhiệt, v.v.). "Hiệu ứng phụ" thường đề cập đến một môi trường thực thi lý tưởng hóa trong đó môi trường đó không có gì thay đổi trừ khi chương trình thay đổi rõ ràng. Nhưng nếu bạn đang gọi square(x) bạn muốn trạng thái máy tính bên ngoài thay đổi, bạn có thể coi đó là một tác dụng phụ.
Kristopher Johnson

Đối với tôi hình minh họa đầu tiên làm cho ý nghĩa hoàn hảo. Tuy nhiên, cái thứ hai ít hơn như vậy. Tôi tin rằng tác dụng phụ nên được xác định liên quan đến một môi trường / phạm vi nhất định. Nếu bạn xem xét toàn bộ vũ trụ, sẽ không có thứ gọi là không có tác dụng phụ. Ngay cả khi bạn giới hạn nó với máy tính, chức năng của bạn sẽ ảnh hưởng đến các quá trình khác trong đó CPU sẽ không hoạt động giống nhau. Nếu bạn giới hạn phạm vi cho những thứ có thể truy cập trong phạm vi chức năng cục bộ, thì chúng ta có một cái gì đó để nói về.
func7

20

Tôi nghĩ rằng các câu trả lời hiện có là khá tốt. Tôi muốn giải thích một số khía cạnh mà IMO chưa được nhấn mạnh đủ.

Trong toán học, một hàm chỉ là một ánh xạ từ một bộ giá trị đến một giá trị. Vì vậy, được đưa ra một hàm fvà một giá trị x, f(x)sẽ luôn luôn là kết quả tương tự y. Bạn cũng có thể thay thế f(x)bằng ymọi nơi trong một biểu thức và sẽ không có gì thay đổi.

Cái được gọi là hàm (hoặc thủ tục) trong nhiều ngôn ngữ lập trình là cấu trúc (đoạn mã) có thể được thực thi vì:

  1. Nó tính toán một hàm theo nghĩa toán học, nghĩa là các giá trị đầu vào đã cho, nó trả về một kết quả hoặc
  2. Nó tạo ra một số hiệu ứng, ví dụ như in một cái gì đó lên màn hình, thay đổi giá trị trên cơ sở dữ liệu, phóng tên lửa, ngủ trong 10 giây, gửi SMS.

Vì vậy, các hiệu ứng có thể liên quan đến trạng thái mà còn liên quan đến các khía cạnh khác như bắn tên lửa hoặc tạm dừng thực thi trong vài giây.

Thuật ngữ tác dụng phụ có thể nghe có vẻ tiêu cực nhưng thông thường, hiệu ứng của việc gọi một chức năng là mục đích của chính chức năng đó. Tôi cho rằng, vì thuật ngữ hàm ban đầu được sử dụng trong Toán học, tính toán một giá trị được coi là hiệu ứng chính của hàm trong khi mọi hiệu ứng khác được coi là tác dụng phụ . Một số ngôn ngữ lập trình sử dụng thủ tục thuật ngữ để tránh nhầm lẫn với các hàm theo nghĩa toán học.

Lưu ý rằng

  1. Một số thủ tục hữu ích cho cả giá trị trả về và tác dụng phụ của chúng.
  2. Một số thủ tục chỉ tính toán một giá trị kết quả và không có hiệu ứng khác. Chúng thường được gọi là các hàm thuần túy vì tất cả những gì chúng làm là tính toán một hàm theo nghĩa toán học.
  3. Một số quy trình, ví dụ như sleep()trong Python, chỉ hữu ích cho các hiệu ứng (phụ) của chúng ,. Chúng thường được mô hình hóa như các hàm trả về một giá trị đặc biệt None, unithoặc ()hoặc ..., chỉ đơn giản chỉ ra rằng tính toán đã kết thúc chính xác.

2
Theo ý kiến ​​khiêm tốn của tôi, đây nên là câu trả lời được chấp nhận. Khái niệm về một tác dụng phụ thậm chí chỉ có ý nghĩa về mặt chức năng toán học. Một thủ tục được thiết kế để đơn giản nhóm một nhóm các hướng dẫn theo cách có cấu trúc trong khi cho phép bạn chuyển đến tập hợp đó từ bất cứ đâu và quay lại một cách thuận tiện. Không có tác dụng dự định chính và những tác dụng phụ. Bạn có thể nói ném ngoại lệ là tác dụng phụ của thủ tục, vì nó phá vỡ ý định của thủ tục nhằm đưa bạn trở lại nơi bạn rời đi và tiếp tục hình thức thực hiện ở đó.
Didier A.

4

Một tác dụng phụ là khi một hoạt động có ảnh hưởng đến một biến / đối tượng nằm ngoài mục đích sử dụng.

Nó có thể xảy ra khi bạn thực hiện cuộc gọi đến một hàm phức tạp có tác dụng phụ là thay đổi một số biến toàn cục, mặc dù đó không phải là lý do bạn gọi nó (có thể bạn đã gọi nó để trích xuất một cái gì đó từ cơ sở dữ liệu).

Tôi thừa nhận rằng tôi gặp khó khăn khi đưa ra một ví dụ đơn giản mà trông không hoàn toàn bị chiếm đoạt, và các ví dụ từ những thứ tôi đã làm việc quá lâu để đăng ở đây (và vì nó liên quan đến công việc, nên có lẽ tôi không nên ).

Một ví dụ tôi đã thấy (cách đây một thời gian) là một chức năng mở kết nối cơ sở dữ liệu nếu kết nối ở trạng thái đóng. Vấn đề là nó được cho là đóng kết nối ở cuối chức năng, nhưng nhà phát triển đã quên thêm mã đó. Vì vậy, ở đây, có một tác dụng phụ ngoài ý muốn : gọi một thủ tục được cho là chỉ thực hiện một truy vấn và tác dụng phụ là kết nối vẫn mở và nếu chức năng được gọi hai lần liên tiếp, một lỗi sẽ xuất hiện cho biết kết nối là đã mở


Ok, vì bây giờ mọi người đang đưa ra ví dụ, tôi nghĩ tôi cũng sẽ như vậy;)

/*code is PL/SQL-styled pseudo-code because that's what's on my mind right now*/

g_some_global int := 0; --define a globally accessible variable somewhere.

function do_task_x(in_a in number) is
begin
    b := calculate_magic(in_a);
    if b mod 2 == 0 then
        g_some_global := g_some_global + b;
    end if;
    return (b * 2.3);
end;

Các chức năng do_task_xchính hiệu lực thi hành trở về kết quả của một số tính toán, và một bên ảnh hưởng của thể sửa đổi một biến toàn cầu.

Tất nhiên, đó là chính và đó là tác dụng phụ có thể được mở để giải thích và có thể phụ thuộc vào việc sử dụng thực tế. Nếu tôi gọi hàm này cho mục đích sửa đổi toàn cục và tôi loại bỏ giá trị trả về hơn tôi nói rằng sửa đổi toàn cục là hiệu ứng chính.


2
Tôi không nghĩ rằng đây là một định nghĩa phổ quát tốt. Nhiều lập trình viên cố tình sử dụng các cấu trúc đặc biệt cho tác dụng phụ của họ.
CB Bailey

@ Charles: Đủ công bằng. Trong trường hợp đó, bạn sẽ định nghĩa nó như thế nào?
Thất vọngWithFormsDesigner

2
Tôi nghĩ rằng @KristopherJohnson có định nghĩa rõ ràng nhất. Bất cứ điều gì làm thay đổi trạng thái của chương trình hoặc môi trường của nó hoặc tạo ra hiệu ứng thế giới thực như tạo đầu ra.
CB Bailey

@Charles Bailey: Điều đó không thay đổi định nghĩa. Sử dụng những thứ cho tác dụng phụ là tốt. Miễn là bạn hiểu rằng có tác dụng phụ. Nó không thay đổi bất cứ điều gì về định nghĩa này.
S.Lott

1
@SLott: Định nghĩa trong câu trả lời này (tức là đoạn đầu tiên) bao gồm mệnh đề: "ngoài mục đích sử dụng". Tôi nghĩ rằng nhận xét của tôi là công bằng.
CB Bailey

3

Trong khoa học máy tính, một chức năng hoặc biểu thức được cho là có tác dụng phụ nếu nó sửa đổi một số trạng thái hoặc có tương tác quan sát được với các chức năng gọi hoặc thế giới bên ngoài.

Từ Wikipedia - Tác dụng phụ

Một hàm, theo nghĩa toán học, là một ánh xạ từ đầu vào đến đầu ra. Hiệu quả dự định của việc gọi một hàm là để nó ánh xạ đầu vào tới đầu ra mà nó trả về. Nếu hàm làm bất cứ điều gì khác, nó không thành vấn đề, nhưng nếu nó có bất kỳ hành vi nào không ánh xạ đầu vào vào đầu ra, thì hành vi đó được biết là một tác dụng phụ.

Nói một cách tổng quát hơn, một hiệu ứng phụ là bất kỳ hiệu ứng nào không phải là hiệu ứng dự định của người thiết kế công trình.

Một hiệu ứng là bất cứ điều gì ảnh hưởng đến một diễn viên. Nếu tôi gọi một chức năng gửi cho bạn gái của tôi một tin nhắn văn bản chia tay, điều đó ảnh hưởng đến một loạt các diễn viên, tôi, cô ấy, mạng của công ty điện thoại di động, v.v. để trả lại cho tôi một ánh xạ từ đầu vào của tôi. Vì vậy đối với:

   public void SendBreakupTextMessage() {
        Messaging.send("I'm breaking up with you!")
   }

Nếu điều này được dự định là một hàm, thì điều duy nhất nó nên làm là trả về void. Nếu nó là hiệu ứng phụ miễn phí, nó thực sự không nên gửi tin nhắn văn bản.

Trong hầu hết các ngôn ngữ lập trình, không có cấu trúc cho một hàm toán học. Không có cấu trúc được dự định sẽ được sử dụng như vậy. Đó là lý do tại sao hầu hết các ngôn ngữ nói rằng bạn có phương pháp hoặc thủ tục. Theo thiết kế, chúng được dự định để có thể làm nhiều hiệu ứng hơn. Theo cách nói lập trình thông thường, không ai thực sự quan tâm đến ý định của phương thức hay thủ tục là gì, vì vậy khi ai đó nói hàm này có tác dụng phụ, nghĩa là, cấu trúc này không hoạt động như một hàm toán học. Và khi ai đó nói rằng hàm này không có tác dụng phụ, ý họ là, cấu trúc này hoạt động hiệu quả như một hàm toán học.

Theo định nghĩa, một hàm thuần túy luôn có tác dụng phụ miễn phí. Hàm thuần túy, là một cách để nói, hàm này, mặc dù nó sử dụng một cấu trúc cho phép nhiều hiệu ứng hơn, nhưng chỉ có tác dụng tương đương với hàm của hàm toán học.

Tôi thách thức bất cứ ai nói với tôi khi chức năng miễn phí tác dụng phụ sẽ không thuần túy. Trừ khi hiệu ứng dự định chính của ngữ cảnh của câu sử dụng thuật ngữ thuần túy và hiệu ứng phụ miễn phí không phải là hiệu ứng dự định toán học của một hàm, thì những cái đó luôn luôn bằng nhau.

Như vậy, đôi khi, mặc dù hiếm hơn, và tôi tin rằng đây là sự khác biệt thiếu và cũng là hiểu lầm mọi người (vì đó không phải là giả định phổ biến nhất) trong câu trả lời được chấp nhận, nhưng đôi khi người ta cho rằng tác dụng dự định của chức năng lập trình là để ánh xạ đầu vào thành đầu ra, trong đó đầu vào không bị ràng buộc với các tham số rõ ràng của hàm, nhưng đầu ra bị ràng buộc với giá trị trả về rõ ràng. Nếu bạn cho rằng đó là hiệu ứng mong muốn, thì một hàm đọc tệp và trả về một kết quả khác dựa trên những gì trong tệp vẫn không có tác dụng phụ, vì bạn đã cho phép các đầu vào đến từ những nơi khác trong hiệu ứng dự định của bạn.

Vì vậy, tại sao tất cả điều này quan trọng?

Đó là tất cả về kiểm soát và giữ nó. Nếu bạn gọi một hàm và nó làm một cái gì đó khác thì trả về một giá trị, thật khó để suy luận về hành vi của nó. Bạn sẽ cần phải nhìn vào bên trong hàm để tìm mã thực tế để đoán nó đang làm gì và khẳng định tính chính xác của nó. Tình huống lý tưởng là nó rất rõ ràng và dễ dàng để biết đầu vào mà hàm đang sử dụng là gì và nó không làm gì khác sau đó trả lại một đầu ra cho nó. Bạn có thể thư giãn điều này một chút và nói rằng biết chính xác đầu vào mà nó đang sử dụng không hữu ích như chắc chắn nó không làm gì khác mà bạn có thể không biết sau đó trả về một giá trị, vì vậy có thể bạn hài lòng với việc chỉ thực thi rằng nó không làm gì khác sau đó ánh xạ đầu vào, bất kể nó lấy từ đâu, đến đầu ra.

Trong hầu hết các trường hợp, quan điểm của một chương trình là có các hiệu ứng khác sau đó ánh xạ mọi thứ đi vào những thứ sắp ra. Ý tưởng kiểm soát hiệu ứng phụ là bạn có thể tổ chức mã theo cách dễ hiểu và lý do hơn. Nếu bạn đặt tất cả các tác dụng phụ lại với nhau, ở một nơi rất rõ ràng và trung tâm, bạn sẽ dễ dàng biết nơi để tìm và tin rằng đây là tất cả những gì đang xảy ra, không còn nữa. Nếu bạn cũng có đầu vào rất rõ ràng, nó sẽ giúp kiểm tra hành vi cho các đầu vào khác nhau và nó dễ sử dụng hơn, vì bạn không cần thay đổi đầu vào ở nhiều nơi khác nhau, một số có thể không rõ ràng, chỉ là để có được những gì bạn muốn.

Bởi vì điều hữu ích nhất để hiểu, lý do và kiểm soát hành vi của một chương trình là để tất cả các đầu vào được nhóm lại rõ ràng với nhau và rõ ràng, cũng như tất cả các tác dụng phụ được nhóm lại với nhau và rõ ràng, đây thường là những gì mọi người nói về khi họ nói tác dụng phụ, tinh khiết, vv

Bởi vì hữu ích nhất là nhóm các tác dụng phụ và nhân chứng của họ, đôi khi mọi người sẽ chỉ có nghĩa như vậy, và phân biệt nó bằng cách nói rằng nó không thuần túy, nhưng vẫn "không có tác dụng phụ". Nhưng tác dụng phụ có liên quan đến "hiệu ứng chính dự định" giả định, vì vậy đó là một thuật ngữ theo ngữ cảnh. Điều này tôi thấy ít được sử dụng, mặc dù đáng ngạc nhiên là nó được nói đến rất nhiều trong chủ đề này.

Cuối cùng, idempotent có nghĩa là gọi hàm này nhiều lần với cùng một đầu vào (không quan trọng chúng đến từ đâu) sẽ luôn dẫn đến các hiệu ứng tương tự (tác dụng phụ hay không).


Tôi nghĩ rằng một vấn đề lớn với việc giải thích các tác dụng phụ là cho đến khi bạn sử dụng một ngôn ngữ như Ocaml hoặc Haskell, có thể rất khó để lý giải về lập trình (gần như!) Không có tác dụng phụ.
Jamie Strauss

2

Trong lập trình, tác dụng phụ là khi một thủ tục thay đổi một biến từ bên ngoài phạm vi của nó. Tác dụng phụ không phụ thuộc vào ngôn ngữ. Có một số loại ngôn ngữ nhằm loại bỏ tác dụng phụ (ngôn ngữ chức năng thuần túy), nhưng tôi không chắc có ngôn ngữ nào yêu cầu tác dụng phụ hay không, nhưng tôi có thể sai.

Theo tôi biết, không có tác dụng phụ bên trong và bên ngoài.


Nói chính xác hơn, các ngôn ngữ chức năng thuần túy tách biệt rõ ràng mã miễn phí có hiệu lực phụ với mã khác, trong khi các ngôn ngữ khác không có cơ chế phân biệt giữa mã thuần và mã không tinh khiết. Hầu hết các chương trình cần phải có tác dụng phụ để được sử dụng.
Giorgio

Tôi nghĩ rằng một số ngôn ngữ lập trình trước gui như MS-BASIC và QBasic có thể gần với ngôn ngữ 'chỉ có tác dụng phụ' như bạn có thể nhận được. Và có, bạn có thể có cả tác dụng phụ bên trong và bên ngoài.
James K

0

Đây là một ví dụ đơn giản:

int _totalWrites;
void Write(string message)
{
    // Invoking this function has the side effect of 
    // incrementing the value of _totalWrites.
    _totalWrites++;
    Debug.Write(message);
}

Định nghĩa về tác dụng phụ không đặc trưng cho lập trình nên chỉ cần tưởng tượng các tác dụng phụ của thuốc hoặc ăn quá nhiều thực phẩm.


Nhưng nếu tin nhắn xuất hiện dưới dạng tham chiếu và bạn thay đổi tin nhắn trong phương thức của mình thì đó có thể là tác dụng phụ. Tôi có đúng không?
Amir Rezaei

Thực tế là biểu thức x++sửa đổi biến xthường được coi là một tác dụng phụ. Giá trị đó của biểu thức là giá trị tăng trước của x; đây là phần hiệu ứng không phụ của biểu thức.
CB Bailey

@Charles - Tôi đồng ý, mặc dù ví dụ ban đầu không rõ ràng như ví dụ hiện tại.
ChaosPandion

@Amir - Chà, điều đó thực sự phụ thuộc vào ngôn ngữ. Nếu đây là C # thì điều này sẽ không được coi là tác dụng phụ.
ChaosPandion

@ChaosPandion: Cá nhân tôi không đồng ý. Ví dụ ban đầu đơn giản và rõ ràng hơn nhiều.
CB Bailey

-2

Một tác dụng phụ là những điều xảy ra trong mã không rõ ràng.

Ví dụ: giả sử bạn có lớp này

public class ContrivedRandomGenerator {
   public int Seed { get; set; }

   public int GetRandomValue()
   {
      Random(Seed);
      Seed++;
   }
}

Khi bạn ban đầu tạo lớp, bạn cung cấp cho nó một hạt giống.

var randomGenerator = new ContrivedRandomGenerator();
randomGenerator.Seed = 15;
randomGenerator.GetRandomValue();

Bạn không biết nội bộ, bạn chỉ mong nhận được một giá trị ngẫu nhiên và bạn sẽ mong đợi RandomGenerator. Vẫn còn 15 ... nhưng thực tế không phải vậy.

Lệnh gọi có tác dụng phụ là thay đổi giá trị Seed.


10
Tác dụng phụ không phải được ẩn. Bạn đang nghĩ về việc sử dụng thông tục hoặc y tế; trong lập trình, một tác dụng phụ chỉ đơn giản là sửa đổi một số trạng thái.
Aaronaught

1
In ra bàn điều khiển là một tác dụng phụ. Nó không bị ẩn. Từ Wikipedia : "Trong khoa học máy tính, một chức năng hoặc biểu thức được cho là có tác dụng phụ nếu ngoài việc trả về một giá trị, nó còn sửa đổi một số trạng thái hoặc có tương tác quan sát được với các chức năng gọi hoặc thế giới bên ngoài ."

Tác dụng phụ là làm thế nào các chức năng không (tức là thủ tục) hoàn thành bất kỳ công việc nào. X = 1; X = Y (10) là hai hàm thuần túy. Khi bạn bước ra ngoài vương quốc "x = anything", có nên ghi đầu ra vào màn hình | ổ đĩa , đó là một tác dụng phụ.
James K

Tôi nghĩ rằng bởi 'ẩn', anh ta có nghĩa là không rõ ràng. Giống như trong x = f (y, z) x có thể được giả định là dựa trên y và z. Trong khi đó, Proc (x, y, z) không cho bạn biết gì về những gì đang diễn ra. Mỗi biến có thể được thay đổi, hoặc không có. Proc có thể là một tương tự với f, hoặc hoàn toàn không liên quan. Một hàm thuần có một câu trả lời duy nhất: 'x'. Ngoài ra, đó là một tác dụng phụ. Hoàn toàn có ý định, nhưng tác dụng phụ.
James K

Cũng giống như hiểu 0, trước tiên bạn phải hiểu 1: Để hiểu tác dụng phụ, trước tiên bạn phải hiểu chức năng.
James K
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.