Lý do cơ bản đằng sau quyết định thiết kế để có các không gian tên riêng cho các giá trị và hàm trong Common Lisp là gì? Các đối số cho và chống lại nó là gì?Tại sao nhiều không gian tên?
Trả lời
Lisp thông thường về cơ bản là hậu duệ của bản gốc Lisp 1.5, hay đúng hơn là một sự thống nhất các phương ngữ phân tách của nó. Bản gốc Lisp 1.5 là ngày nay được gọi là Lisp-2. Bởi vì nó đã trở lại vào những năm sáu mươi và thực tế là bạn có thể vượt qua các chức năng cho các chức năng khác là đủ kỳ lạ. Không ai có thể nghĩ đến việc cho phép họ chia sẻ cùng một không gian tên. Hầu như bất kỳ ngôn ngữ nào được phát minh ngày nay với sự hỗ trợ cho các hàm bậc cao và các hàm ẩn danh chọn cách tiếp cận không gian tên đơn. Bao gồm Clojure, mà là nếu không gần gũi hơn với Common Lisp hơn để Đề án.
Đề án, như Clojure, ban đầu không phải là một phương ngữ phân biệt từ Lisp 1.5, và cho mục đích của chúng có ý nghĩa. Tất nhiên, trong Clojure, vectơ, bản đồ băm, tập hợp và tất cả cũng có thể được áp dụng cho đối số, do đó, trong một ý nghĩa, một vector trong Clojure có thể được xem như một hàm lấy số tự nhiên và tạo ra một giá trị từ cái đó.
Vui lòng xem giấy của Richard P. Gabriel Technical Issues of Separation in Function Cells and Value Cells để được điều trị đầy đủ về mặt học thuật của chủ đề này.
Tôi thực sự thích có một số không gian tên (thậm chí nhiều hơn hai không gian); nó làm cho mọi thứ dễ dàng hơn cho người sử dụng và trình biên dịch-nhà văn (thực hiện):
CL-USER> (defclass test()())
#<STANDARD-CLASS TEST>
CL-USER> (defun test())
TEST
CL-USER> (defparameter test 42)
TEST
CL-USER> (describe 'test)
COMMON-LISP-USER::TEST
[symbol]
TEST names a special variable:
Value: 42
TEST names a compiled function:
Lambda-list:()
Derived type: (FUNCTION NIL (VALUES NULL &OPTIONAL))
Source form:
(LAMBDA()
(DECLARE (MUFFLE-CONDITIONS COMPILER-NOTE))
(PROGN
(SB-INT:NAMED-LAMBDA TEST
NIL
(BLOCK TEST))))
TEST names the standard-class #<STANDARD-CLASS TEST>:
Direct superclasses: STANDARD-OBJECT
No subclasses.
Not yet finalized.
No direct slots.
; No value
CL-USER> (make-instance 'test)
#<TEST {1005B1D601}>
CL-USER> (test)
NIL
CL-USER> test
42
CL-USER>
Bạn có thể giải thích lý do tại sao bạn cho rằng "nó giúp mọi người dễ dàng hơn" không? Tôi đã không viết nhiều Đề án, nhưng tôi đã viết một số tiền hợp lý của Python, và không bao giờ có một vấn đề với muốn cung cấp cho một lớp, dụ, và/hoặc phương pháp cùng tên. Cho rằng vấn đề, ngay cả trong Common Lisp nơi tôi có thể tái sử dụng tên như thế này, tôi không nghĩ rằng tôi đã từng có. Các trường hợp có xu hướng là danh từ, hàm có xu hướng là động từ, vv – Ken
@Ken: Tôi thường viết những thứ như '(defun foo (danh sách) (danh sách (danh sách thanh)))' trong CL, không hoạt động với single không gian tên. Phải đặt tên cho các đối số của tôi những thứ như 'lyst' hoặc' lst' trong Scheme khiến tôi hơi điên. – Pillsy
Pillsy: Đúng vậy. Sau đó, một lần nữa, gọi đối số 'danh sách' sẽ khiến tôi hơi điên, vì nó không mang tính mô tả. Tôi gọi nó là 'source' hoặc' target' hoặc 'haystack' hoặc' words' cho biết mục đích của danh sách là gì. Nếu tôi gọi params theo kiểu của chúng, 90% số arg của tôi sẽ là 'list'. :-) – Ken
Mặc dù có thể có rất nhiều lý lẽ mỗi chiều về mặt lý thuyết, tôi muốn đặt cược rằng nó phần lớn là triết học trong xứ. Đề án, một Lisp-1, thích sự thanh lịch hơn tính thực tiễn, và đã chọn cú pháp define
tương tự cho các biến và hàm, làm cho một không gian tên duy nhất cảm thấy tự nhiên (và khuyến khích một kiểu lập trình chức năng). Lisp thường có xu hướng thích tính thực tiễn và sức mạnh hơn sự tao nhã, và là một nỗ lực trong việc xây dựng sự đồng thuận, vì vậy nhìn thấy một giải pháp hai không gian tên hiện có được chấp nhận rộng rãi và hoạt động tốt, chấp nhận nó.
Trên thực tế, tuy nhiên, nó chủ yếu có nghĩa là ba điều:
- Trong Common Lisp (và khác Lisp-2 của), bạn phải sử dụng
funcall
rất nhiều - Trong Scheme (và khác Lisp-1), bạn phải cẩn thận không ghi đè tên chức năng cần thiết với các biến; ví dụ. đối số chức năng như
lst
thay vìlist
- Trên Internet, sẽ có lập luận
Đây là một yếu tố quan trọng trong lý do tại sao một số người thích một Lisp khác, tuy nhiên.
Kết quả của sự khác biệt đi sâu hơn so với chỉ sử dụng 'funcall' hoặc tránh xung đột tên: sử dụng các hàm bậc cao hơn trong Đề án là tự nhiên hơn, do đó thành ngữ hơn, do đó trình biên dịch sẽ làm việc chăm chỉ để tối ưu hóa nó. Tuy nhiên, trong CL, nếu bạn đang sử dụng 'defvar' để định nghĩa một biến, và sau đó' funcall' nó, thì trình biên dịch rất có khả năng biên dịch nó thành mã chậm hơn nhiều so với sử dụng định nghĩa hàm. Điều này tương tự như CLers thích các cấu trúc vòng lặp và các lược đồ thích các cuộc gọi đuôi hơn. Nhưng tất nhiên điểm thứ ba của bạn là quan trọng nhất ... –
Đó là sự thật, và một phần của ý tôi là "khuyến khích một phong cách lập trình chức năng" --- cảm ơn vì đã làm cho nó rõ ràng hơn. – JasonFruit
Ngoài các vấn đề khác được đề cập ở trên, có một không gian tên riêng cho các chức năng làm cho các macro không hợp vệ sinh của CL ít có khả năng cắn người dùng macro hơn. Trong CL, một tên bị ràng buộc tại điểm gọi xuất hiện trong khi mở rộng macro sẽ có định nghĩa được sử dụng tại điểm gọi, không phải là định nghĩa được sử dụng khi macro được xác định. Vì vậy, trong một phiên bản CL của Lisp-1, nếu macro mở rộng đến một cuộc gọi trên hàm LIST, và LIST được định nghĩa là một biến tại điểm mà macro được gọi, macro sẽ bị trục trặc. (Lưu ý rằng gensyms không giải quyết vấn đề này, không giống như các vấn đề nghịch đảo mà họ làm giải quyết.)
Điều này không xảy ra trong Đề án bởi vì các lược đồ mặc định là hợp vệ sinh: tất cả các tên được sử dụng trong việc mở rộng macro đều có nghĩa là macro được xác định, không phải nơi được sử dụng.
- 1. Tại sao System.Web.HttpUtility.UrlEncode cho tên không gian tên không tồn tại trong Visual C# 2008?
- 2. Tại sao không gian tên cột hợp lệ trong SqlServer?
- 3. Rails - Savon đặt nhiều không gian tên
- 4. loại tên hoặc không gian tên không tồn tại trong không gian tên
- 5. Tên loại hoặc không gian tên 'Mvc' không tồn tại trong không gian tên 'System.Web'
- 6. Tên loại hoặc không gian tên 'Caching' không tồn tại trong không gian tên 'System.Runtime'
- 7. Tên loại hoặc không gian tên 'ServiceBus' không tồn tại trong không gian tên 'Microsoft'
- 8. Tên kiểu hoặc không gian tên UpdatePanel không tồn tại trong không gian tên System.Web.UI
- 9. Tên loại hoặc không gian tên 'DirectoryServices' không tồn tại trong không gian tên?
- 10. Tên "LocalizedStrings" không tồn tại trong không gian tên
- 11. Tên loại hoặc không gian tên 'Linq' không tồn tại
- 12. Tại sao /^(.+)+Q$/.test("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ") mất quá nhiều thời gian?
- 13. Thẻ 'XXX' không tồn tại trong không gian tên clr của không gian tên XML: YYY '
- 14. Tại sao Parallel.ForEach không chạy nhiều luồng?
- 15. C# Không gian tên/thư mục: khi nào được tổ chức quá/tạo quá nhiều không gian tên không đúng?
- 16. Tại sao hiển thị lỗi xmlns tiền tố không gian tên không mong muốn trong android?
- 17. Tại sao không có cú pháp XPath cho các nút đủ điều kiện không gian tên?
- 18. Tại sao các ký tự XML động không thừa kế không gian tên mặc định
- 19. Tại sao Eclipse PHP không nhận ra các khai báo không gian tên?
- 20. Tại sao kiểu dáng và bố cục không sử dụng không gian tên android?
- 21. Tại sao không phải là lớp Loại trong không gian tên System.Reflection?
- 22. Tại sao không "sử dụng quá tải" làm việc với "sử dụng không gian tên: autoclean"?
- 23. Không gian tên trong Redis?
- 24. 'Hệ thống': không gian tên có tên này không tồn tại
- 25. Tại sao một số chức năng trong không gian tên có thể truy cập được nếu không có tiền tố phạm vi không gian tên?
- 26. 'ManagementClass' không tồn tại trong không gian tên 'System.Management'
- 27. Điểm không tồn tại trong không gian tên System.Drawing
- 28. Thẻ không tồn tại trong không gian tên XML
- 29. System.Web.Helpers không tồn tại trong không gian tên: WebImage
- 30. Microsoft.Reporting không tồn tại trong không gian tên
(Có lẽ cũng đáng nói rằng một hàm trong lisp cũ) tương tự như một hàm trong Emacs Lisp - chỉ là một danh sách bắt đầu bằng 'lambda'.) –
Thật sao? Tôi không ý kiến. Vì vậy, họ chỉ thay đổi các biến ràng buộc mức thấp trong eval trước khi áp dụng nó? Chết tiệt, điều đó phải tốn kém. – Zorf
Rich Hicky nói về cách anh tránh được một số cạm bẫy bình thường đi kèm với Lisp-1. (tìm clojure trên blib.tv). Tôi không thể nhớ chính xác vì vậy bạn muốn tự mình giải thích nó. – nickik