Quy ước đặt tên cho các chức năng có tác dụng phụ? [đóng cửa]


9

Tôi nghe ai đó nói rằng ngôn ngữ của họ có một quy ước trong đó tên của các hàm biến đổi trạng thái phải kết thúc bằng dấu chấm than. Tôi đang cố gắng viết mã chức năng nhiều hơn và tôi thích ý tưởng bằng cách nào đó đánh dấu các chức năng theo trạng thái hiệu ứng phụ của chúng tức là không có, tác dụng phụ bên trong, tác dụng phụ bên ngoài (Tôi không biết gì về thuật ngữ fp đúng nhưng bạn hiểu ý tôi mong).

Rõ ràng là tôi dễ dàng đưa ra kế hoạch đặt tên của riêng mình nhưng tôi đã tự hỏi liệu những kế hoạch / quy ước như vậy đã tồn tại trước khi tôi đi và thực hiện một kế hoạch.

chỉnh sửa: Cảm ơn tất cả các phản hồi, đó chính xác là những gì tôi đã theo dõi và tôi thấy chúng thực sự hữu ích. Có lẽ tôi nên đề cập đến việc tôi đang cấu trúc lại một số javascript cũ, vì vậy, trong khi các ngôn ngữ được nhập tĩnh có thể có thể thực thi một sự khác biệt giữa mã có và không có tác dụng phụ, tôi sẽ phải dựa vào quy ước đặt tên tự áp đặt.

edit2: Đối với các mod đóng cái này là chủ yếu dựa trên ý kiến, tôi phải không đồng ý. Tôi đã hỏi những gì, nếu có, các quy ước được sử dụng phổ biến - đây là định nghĩa của bất kỳ ai, một câu hỏi thực tế không phải là ý kiến!


1
Điều này có thể thay đổi giữa các ngôn ngữ và có khả năng rất định hướng ý kiến.
David Arno

1
Ví dụ, quy ước của Scala là khai báo các phương thức không có dấu ngoặc đơn (giống như các thuộc tính), trừ khi chúng có tác dụng phụ. Nhưng bạn không thể sử dụng ngôn ngữ này trong bất kỳ ngôn ngữ nào khác mà tôi biết. Điểm cảm thán có vẻ kinh khủng đối với tôi; có quá nhiều cách sử dụng khác cho biểu tượng đó và tôi sẽ thấy nó được sử dụng để đánh dấu các phương thức gây mất tập trung.
Robert Harvey

2
@RobertHarvey Tôi tin rằng Scheme là ngôn ngữ sử dụng quy ước đó và quy ước tồn tại bởi vì toán tử biến đổi trạng thái của một biến là !(nó sẽ không hợp lệ về mặt cú pháp để biến đổi trạng thái của một biến mà không có toán tử đó, nếu bộ nhớ phục vụ ), vì vậy nó thực sự là một quy ước khá hợp lý trong ngôn ngữ đó .
Phục vụ

3
@Servy Standard Scheme có thể set!thay đổi một biến, nhưng không có !toán tử độc lập . Quy ước tồn tại bởi vì Lisp có lịch sử sử dụng các ký hiệu trong mã định danh để truyền đạt ý nghĩa do rất ít hạn chế về định danh hợp lệ là gì. Việc thiếu các hạn chế tồn tại do sự tập trung của Lisp vào các macro và ngôn ngữ cụ thể của miền.
Jack

1
Ruby cũng sử dụng !quy ước (ví dụ: cho downcasedowncase!), nhưng nó chỉ ra "nguy hiểm" nói chung hơn là "tác dụng phụ".
Andrew

Câu trả lời:


8

Thực hiện theo phân tách truy vấn lệnh . Các hàm trả về giá trị không có tác dụng phụ, các hàm có tác dụng phụ không trả về giá trị.

Nó cũng giúp đặt tên các hàm trả về giá trị sau thứ chúng trả về, tức là danh từ hoặc tính từ. Trong khi các chức năng có tác dụng phụ nên được đặt tên theo hiệu ứng mà chúng thực hiện, tức là một động từ.

Vì vậy, ví dụ myArray.sort()có một tác dụng phụ, nó sắp xếp các mảng. Vì vậy, nó không trả lại bất cứ điều gì và được đặt tên theo một động từ. Trong khi đó, myArray.sorted()trả về một bản sao được sắp xếp của myArray. Do đó, nó không có bất kỳ tác dụng phụ nào và được đặt tên theo thứ mà nó trả lại.

FYI, ý tưởng trên (danh từ / tính từ cho các hàm thuần túy và động từ cho các hàm tạo hiệu ứng phụ) là một tiêu chuẩn trong Swift 3.

Đặt tên hàm và phương thức theo tác dụng phụ của chúng

  • Những người không có tác dụng phụ nên đọc như cụm danh từ.
  • Những người có tác dụng phụ nên đọc như cụm động từ bắt buộc.

( https://swift.org/documentation/api-design-guferences/#strive-for-fluent-usage )


4

Vấn đề cơ bản là các tác dụng phụ không được ghi lại trong hệ thống loại. Sử dụng quy ước đặt tên hàm là một thay thế kém cho xác minh tĩnh. Có một vài cách xung quanh điều này.

Haskell sử dụng các đơn nguyên để ghi lại các hiệu ứng phụ trong một bối cảnh. bindHoạt động đơn nguyên bao gồm các hàm không tinh khiết giống như toán tử thành phần chức năng bình thường tạo ra các hàm thuần túy. Các luật đơn nguyên đảm bảo toán tử này hoạt động tương tự như thành phần thông thường.

Một cách khác là tách riêng tinh khiết khỏi tạp chất bằng cách tách hoàn toàn các biểu thức khỏi các lệnh . Đây là hai loại cú pháp hoàn toàn khác nhau không thể trộn lẫn. Biểu thức có các loại cho phép chúng ta soạn các thuật ngữ. Một định nghĩa, theo định nghĩa, không thể phụ thuộc vào bất kỳ sự gán nào (nó không có quyền truy cập vào cửa hàng ). Các lệnh không có kiểu theo nghĩa truyền thống và không thể trả về giá trị. Họ chỉ có thể tương tác với chương trình bằng cách thay đổi cửa hàng.

Lưu ý rằng các ngôn ngữ "chức năng" an toàn theo kiểu thông thường có thể không tuân theo một trong hai mô hình này. Ví dụ, OCaml và SML không phân biệt chính xác thuần túy với các hàm không tinh khiết.

Cả hai giải pháp này đều hoàn hảo, và đây vẫn là một lĩnh vực nghiên cứu tích cực.


lưu ý rằng haskell cũng có unsafePerformIO
jk.

Tôi không quen thuộc sâu sắc với Haskell. Hầu hết các ngôn ngữ an toàn cung cấp một cách để lật đổ hệ thống loại như là phương sách cuối cùng. Ngoài ra, tên người dùng của bạn khiến tôi khó có thể lấy bất cứ điều gì bạn nói một cách nghiêm túc: D
vườn

@jk unsafePerformIO có thể bị coi nhẹ một cách an toàn trong bối cảnh này. Đó là một lối thoát không có nghĩa là được sử dụng bởi mã thông thường, và nó đi kèm với cảnh báo và cảnh báo quan trọng . Dù sao thì nó cũng không được sử dụng với mã hiệu ứng phụ.
Andres F.

@AresresF. Quan điểm của tôi là không an toàn * là một quy ước đặt tên cho, những thứ không an toàn trong Haskell, có nghĩa là những thứ mà chính chúng thực hiện các tác dụng phụ, mặc dù nó cũng chỉ được sử dụng bởi chính mã triển khai chứ không phải bởi mã người dùng
jk.

3

Gọi ra các phương thức hoặc hàm có vẻ như là một ý tưởng tuyệt vời bởi vì nó có thể giúp loại bỏ thời gian mà mã giới thiệu mức độ không an toàn. Joel Spolsky đi sâu vào ý tưởng này khá nhiều trong bài viết của mình Làm cho mã sai nhìn sai ( http://www.joelonsoftware.com/articles/Wrong.html ) trong đó ông khuyên bạn nên sử dụng một phiên bản ít phổ biến của ký hiệu Hungary để thực hiện ý tưởng nhất định minh bạch hơn trong hệ thống.

Ngôn ngữ mà bạn đang đề cập gần như chắc chắn là Scheme (xem http://doad.plt-scheme.org/doc/html/guide/set_.html để biết ví dụ dễ hiểu). Tôi không nhận thức được bất cứ điều gì toàn cầu.

Tiền tố Java có các phương thức thuộc tính với getsetđể thực hiện một phần mục đích này, nhưng tôi không thực sự biết về bất kỳ quy ước chung nào về loại bạn đề cập bên ngoài thế giới Lisp không (như @gardenhead đã chỉ ra) được nhúng trong hệ thống loại.

Tôi nghĩ, về mặt chính, bạn khá an toàn khi tạo ra một hướng dẫn phong cách cho nhóm của mình, đặc biệt nếu bạn xử lý một vấn đề nào đó với nhiều sự đồng thời trong đó các tác dụng phụ thậm chí còn nguy hiểm hơn bình thường.

Đối với bất cứ điều gì nó có giá trị, tôi có thể nghĩ ra một vài cách để thực hiện điều này bằng các ngôn ngữ ALGOL-esque. Một đơn giản có thể là một tiền tố, như được gợi ý gần đây bởi Spolsky - nói s_về các hoạt động có trạng thái và l_cho các hoạt động không trạng thái.

Một ý tưởng hiện đại hơn có thể là đặt các từ làm tiền tố hoặc hậu tố. Có thể calculatelà một chức năng thuần túy nhưng mutateCalculationlà không tinh khiết.

Cuối cùng, có một mức độ mà rất nhiều điều này nên được xử lý bằng cách tách các mối quan tâm - chỉ có lớp cập nhật cơ sở dữ liệu mới có khả năng cập nhật cơ sở dữ liệu chẳng hạn. Trong trường hợp đó, khá rõ ràng là bạn phải lo lắng về tác dụng phụ trong các lớp trạng thái.


Cảm ơn vì sự trả lời. Tôi đồng ý rằng trong một thế giới lý tưởng, điều này chủ yếu nên được xử lý bằng cách tách rời các mối quan tâm. Trường hợp sử dụng chính của tôi cho một quy ước đặt tên là chọn ra và tái cấu trúc mã cũ không nhất thiết phải được viết với sự thanh lịch và thực hành tốt nhất trong tâm trí! (có thể đôi khi một mình trở lại trong ngày trước khi tôi nhận tôn giáo!)
technicalbloke

Oh và bài viết Joel Spolsky là tuyệt vời, cảm ơn vì liên kết!
kỹ thuật
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.