Tôi có thể sai vì không ai đề cập đến nó, nhưng tôi cũng có ấn tượng rằng lý do cho điều này cũng là di sản ruby của việc có thể gọi các chức năng mà không cần dấu ngoặc.
Arity rõ ràng có liên quan nhưng hãy để nó sang một bên và sử dụng các chức năng mà không cần tranh luận. Trong một ngôn ngữ như javascript, trong đó dấu ngoặc là bắt buộc, thật dễ dàng để tạo sự khác biệt giữa việc truyền một hàm làm đối số và gọi hàm. Bạn gọi nó chỉ khi bạn sử dụng dấu ngoặc.
my_function // argument
(function() {}) // argument
my_function() // function is called
(function() {})() // function is called
Như bạn có thể thấy, việc đặt tên hay không không tạo ra sự khác biệt lớn. Nhưng thuốc tiên và ruby cho phép bạn gọi các chức năng mà không cần dấu ngoặc. Đây là một lựa chọn thiết kế mà cá nhân tôi thích nhưng nó có tác dụng phụ này, bạn không thể chỉ sử dụng tên mà không có dấu ngoặc vì nó có thể có nghĩa là bạn muốn gọi hàm. Đây là những gì &
dành cho. Nếu bạn rời khỏi arity appart trong một giây, hãy thêm vào tên hàm của bạn với &
nghĩa là bạn rõ ràng muốn sử dụng hàm này làm đối số, chứ không phải hàm này trả về.
Bây giờ hàm ẩn danh hơi khác ở chỗ nó chủ yếu được sử dụng làm đối số. Một lần nữa, đây là một sự lựa chọn thiết kế, nhưng lý do đằng sau nó là nó chủ yếu được sử dụng bởi các loại hàm lặp có chức năng làm đối số. Vì vậy, rõ ràng bạn không cần sử dụng &
vì chúng đã được coi là đối số theo mặc định. Đó là mục đích của họ.
Bây giờ vấn đề cuối cùng là đôi khi bạn phải gọi chúng trong mã của mình, bởi vì chúng không phải lúc nào cũng được sử dụng với một loại hàm lặp, hoặc bạn có thể tự mã hóa một trình vòng lặp. Đối với câu chuyện nhỏ, vì ruby là hướng đối tượng, nên cách chính để làm điều đó là sử dụng call
phương thức trên đối tượng. Bằng cách đó, bạn có thể giữ hành vi dấu ngoặc không bắt buộc nhất quán.
my_lambda.call
my_lambda.call()
my_lambda_with_arguments.call :h2g2, 42
my_lambda_with_arguments.call(:h2g2, 42)
Bây giờ ai đó đã đưa ra một phím tắt mà về cơ bản trông giống như một phương thức không có tên.
my_lambda.()
my_lambda_with_arguments.(:h2g2, 42)
Một lần nữa, đây là một sự lựa chọn thiết kế. Bây giờ elixir không hướng đối tượng và do đó gọi không sử dụng mẫu đầu tiên cho chắc chắn. Tôi không thể nói cho Jose nhưng có vẻ như hình thức thứ hai đã được sử dụng trong thuốc tiên vì nó vẫn giống như một lời gọi hàm với một ký tự phụ. Nó đủ gần với một cuộc gọi chức năng.
Tôi đã không nghĩ về tất cả các ưu và nhược điểm, nhưng có vẻ như trong cả hai ngôn ngữ bạn có thể thoát khỏi chỉ với dấu ngoặc miễn là bạn đặt dấu ngoặc bắt buộc cho các hàm ẩn danh. Có vẻ như nó là:
Dấu ngoặc bắt buộc VS Ký hiệu hơi khác nhau
Trong cả hai trường hợp, bạn tạo ra một ngoại lệ vì bạn làm cho cả hai cư xử khác nhau. Vì có một sự khác biệt, bạn cũng có thể làm cho nó rõ ràng và đi cho các ký hiệu khác nhau. Các dấu ngoặc bắt buộc sẽ trông tự nhiên trong hầu hết các trường hợp nhưng rất khó hiểu khi mọi thứ không đi theo kế hoạch.
Bạn đi đây Bây giờ đây có thể không phải là lời giải thích tốt nhất trên thế giới vì tôi đã đơn giản hóa hầu hết các chi tiết. Ngoài ra hầu hết đó là sự lựa chọn thiết kế và tôi đã cố gắng đưa ra lý do cho chúng mà không phán xét chúng. Tôi yêu thuốc tiên, tôi yêu ruby, tôi thích các cuộc gọi chức năng không có dấu ngoặc, nhưng cũng giống như bạn, tôi thấy hậu quả khá sai lầm trong một thời gian.
Và trong thuốc tiên, nó chỉ là dấu chấm bổ sung này, trong khi trong viên ruby bạn có khối trên đầu này. Các khối rất tuyệt vời và tôi ngạc nhiên về việc bạn có thể làm được bao nhiêu chỉ với các khối, nhưng chúng chỉ hoạt động khi bạn chỉ cần một hàm ẩn danh là đối số cuối cùng. Sau đó, vì bạn sẽ có thể xử lý các tình huống khác, ở đây có toàn bộ phương thức / lambda / Proc / khối nhầm lẫn.
Dù sao ... đây là ngoài phạm vi.