Hiểu thành ngữ elisp (giá trị boolean so với đối số được trích dẫn)?


7

Tôi có một số câu hỏi cơ bản về elisp.

Tôi thường thấy một cái gì đó như

(search-forward "something" nil 'noerror)

Và đôi khi tôi thấy một cái gì đó như

(search-forward "something" nil :noerror)

Sự khác biệt là gì và tôi nên thích một hình thức hơn hình thức khác?

Theo như tôi hiểu tất cả mọi thứ nhưng danh sách trống đánh giá là đúng trong bối cảnh boolean. Nhưng làm thế nào đến sau đây:

Khi công cụ tìm kiếm "một cái gì đó" không tồn tại trong bộ đệm, điểm sẽ nhảy đến cuối bộ đệm khi 'noerrorđược sử dụng thay vì t. Khi tđược sử dụng, điểm vẫn ở đó.

Trường hợp đầu tiên:

(search-forward "something" nil 'noerror);; 1.Evaluate this

;; end of buffer 2.point jumps here

Trường hợp thứ hai:

(search-forward "something" nil t);; 1.Evaluate this, 2. Point stays here

;; end of buffer

1
FWIW: Khi tất cả các nilgiá trị không được xử lý giống nhau bởi hàm đã cho, trong mã của tôi, tôi chuyển một ký hiệu có cùng tên hoặc tương tự với tên tham số được sử dụng trong mô tả hàm và thường là chữ hoa. Điều này phục vụ như một lời nhắc nhở cho tôi, khi tôi đọc mã. Ví dụ (search-forward "abc" nil 'NOERROR). Nó là hữu ích nhất cho các đối số tùy chọn hiếm khi được sử dụng.
vẽ

Câu trả lời:


12

Các giá trị Boolean trong elisp hoạt động như sau:

  • nil()(như bạn đã quan sát, là điều tương tự) là sai
  • Hoàn toàn bất cứ điều gì khác là đúng.

Các tbiểu tượng tồn tại như một giá trị 'tinh khiết' true (khi không có lợi cho việc sử dụng giá trị khác), nhưng hầu hết các chức năng sẽ cố gắng để trở lại một cái gì đó mà có thể được nếu không hữu ích, bất cứ khi nào có thể.

Xem thêm C-hig (elisp) nil and t RET

Khi nói đến việc sử dụng các đối số từ khóa hoặc các ký hiệu khác làm nilgiá trị không khi mã chỉ quan tâm nilhoặc không - nil, đó thực sự chỉ là vấn đề sở thích cá nhân. Không có sự khác biệt về mặt thực thi.

Tôi đã từng hỏi điều tương tự , và được thông báo rằng cách tiếp cận đối số từ khóa là phương pháp Lisp-ish phổ biến hơn.

(Tôi đã tự mình sử dụng các đối số từ khóa, một phần để làm nổi bật cú pháp và một phần vì nó phân biệt chúng tốt hơn với các ký hiệu biến và hàm.)

Về ví dụ cụ thể của bạn, hàm sẽ phân biệt giữa các nilgiá trị khác nhau và hành vi đó được bao phủ bởi chuỗi tài liệu của nó:

Đối số thứ ba tùy chọn, nếu t, có nghĩa là nếu không trả về nil(không có lỗi). Nếu không nilvà không t, di chuyển đến giới hạn tìm kiếm và trả lại nil.

Nói chung, bạn sẽ nhận thấy rằng các tài liệu có xu hướng đề cập đến "không phải là" chứ không phải là "đúng" hoặc "t". Nếu bạn thấy "t" thì có khả năng đó là một trường hợp đặc biệt.


Cảm ơn, điều đó đã làm rõ nó cho tôi! Vì vậy, tất cả mọi thứ nhưng không phải là sự thật nhưng t "tinh khiết" là khác nhau từ đó.
clemera

2
Chà, nó vẫn chỉ là một biểu tượng (mặc dù là một câu tự trích dẫn, giống như nillà). Bởi "thuần túy" tôi chỉ có nghĩa là nó tồn tại cụ thể là một giá trị có nghĩa là "đúng", bởi vì đôi khi đó là những gì bạn muốn. Mặc dù vậy, các nilgiá trị không khác vẫn là "đúng" t.
phils

14

Một số tài liệu tham khảo lịch sử là do.

Emacs Lisp mượn nhiều thứ từ Common Lisp, nhưng sự tương đồng chỉ là bề mặt sâu. Biểu tượng dấu hai chấm trong Common Lisp là vòng loại không gian tên. Tên biểu tượng Canonical có hai phần: tên của gói và tên của biểu tượng trong gói đó, ví dụ, cl-user:aproposlà một biểu tượng được xác định trong gói cl-user. Ngoài ra còn có một gói từ khóa đặc biệt được nhập tự động bởi Common Lisp khi nó được bắt đầu. Gói này được sử dụng để liên lạc giữa các gói khác (để nếu các gói cần gửi thông tin tượng trưng cho nhau, họ sẽ không đấu tranh về việc ai phải khai báo). Như bạn có thể đoán, các ký hiệu trong gói đó được viết bằng dấu hai chấm đầu.

Emacs Lisp không có khái niệm về các gói, nhưng dấu hai chấm vẫn đặc biệt ở chỗ nó hướng dẫn người đọc diễn giải biểu thức là biểu tượng tự đánh giá (tức là nó là một biến có giá trị là chính biến đó). Có một số biểu tượng tự đánh giá tích hợp như vậy: tnillà những ví dụ tôi sẽ viết về sau.

Dấu nháy đơn cũng được mượn từ Common Lisp, trong đó nó là macro đọc tiêu chuẩn (nghĩa là mã mà trình thông dịch Lisp thực thi trong khi đọc trong nguồn của chương trình). Nó mở rộng như sau : 'x -> (quote x), trong đó (quote ...)là một hình thức đặc biệt ngăn trình thông dịch Lisp đánh giá nội dung của biểu thức bên trong. Emacs Lisp có ba built-in macro đọc: ', `#, nhưng bạn không thể thêm riêng bạn. Hai cái đầu tiên mở rộng sang (quote ...), tuy nhiên cái thứ hai cho phép cú pháp đặc biệt để xây dựng biểu thức không được đánh giá. #mở rộng (function ...)thành biểu mẫu, hướng dẫn trình thông dịch rằng giá trị phải được tra cứu trong không gian tên hàm.

Các biểu tượng trong Emacs Lisp phải đánh giá một số giá trị (tương tự như các biến trong các ngôn ngữ khác) nếu không đó là lỗi. Tuy nhiên, bạn có thể ngăn chặn đánh giá bằng cách sử dụng mẫu báo giá.

Cuối cùng, sự khác biệt giữa:

(search-forward "something" nil 'noerror)

(search-forward "something" nil :noerror)

Có phải trong trường hợp đầu tiên bạn gọi search-forwardbằng một ký hiệu không có giá trị, chỉ biết tên đó và trong trường hợp thứ hai, bạn đã gọi hàm này với một ký hiệu có giá trị chính là ký hiệu này. Vì vậy, chức năng này không quan tâm đến việc bạn sử dụng cái nào.


Các loại là một công cụ lập trình quan trọng để xác minh tự động các chương trình. Hệ thống loại Emps Lisp tương tự như Common Lisp ở chỗ loại phổ quát của nó (được viết là t) là loại mà tất cả các loại khác có nguồn gốc. Mặt khác, nillà loại mà không có loại nào có nguồn gốc (phần bù của t). Điều này không giống như nhiều ngôn ngữ lập trình phổ biến, có thể không có khái niệm về loại phổ quát hoặc có loại Boolean riêng biệt.

Tuy nhiên, một lần nữa, thật không may, Emacs Lisp đã không sao chép chính xác phần này từ Common Lisp và type-ofchức năng này cho kết quả khó hiểu cho tnil.

Emacs Lisp:

(type-of t) ; symbol

Lisp thường gặp

(type-of t) ; BOOLEAN

Phần mở rộng Lisp chung của Emacs Lisp có chức năng cl-typep, tuy nhiên, có thể giúp hiểu mối quan hệ. Ví dụ

(cl-typep 'noerror t) ; t

tức là bất cứ điều gì 'noerrornó là loại t.


Thông tin bổ sung thú vị, cảm ơn!
clemera

Giải thích tuyệt vời. Tôi cũng đã học được vài điều về Lisp thông thường. Cảm ơn.
gsl
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.