# 'và là một hàm không hợp lệ?


7

Tôi đang cố gắng xem liệu tất cả các giá trị trong danh sách có phải là sự thật hay không. Vì một số lý do, (apply #'and lst)lỗi với:

Hàm không hợp lệ: và

Điều này cũng xảy ra khi tôi cố gắng (cl-reduce #'and lst).

Tuy nhiên, (apply #'max lst)dường như hoạt động tốt.

Ngay bây giờ, tôi đang sử dụng (eval `(and ,@lst)), nhưng điều đó cảm thấy xấu xí.


1
andlà một hình thức đặc biệt chứ không phải là một chức năng.
Dan

2
Bạn nên sử dụng một hàm với hành vi mong muốn, chẳng hạn như (cl-every 'identity lst)hoặc (-all? 'identity lst).
wasamasa

@wasama cảm ơn. Tôi sẽ làm điều đó thay vào đó.
PythonNut

Câu trả lời:


5

Đây thực sự chỉ là một câu trả lời một phần (vì tôi không thể nói tại sao hoặc thực sự cung cấp một cách giải quyết cho nó ngoài những gì bạn đã có).

Theo C-h f and

và là một hình thức đặc biệt trong 'mã nguồn C'.

(và ĐIỀU KIỆN ...)

Eval lập luận cho đến khi một trong số họ mang lại con số không, sau đó trở về con số không. Các đối số còn lại không được lảng tránh chút nào. Nếu không có arg mang lại con số không, hãy trả về giá trị của arg cuối cùng.

[trở lại]

Vì vậy, mặc dù nó hoạt động như một chức năng, nó không phải là một chức năng. Các lỗi tương tự được tạo ra bằng cách sử dụng một macroở nơi and.


7
Nó không hoạt động giống như một hàm: nó dừng đánh giá các đối số một khi chúng không có. (and nil (drop 'bomb))là an toàn miễn andlà không phải là một chức năng.
YoungFrog

3

Để thêm và tóm tắt những gì người khác đã nói:

(functionp 'and) ; ===> nil

Kết thúc câu chuyện.

Từ hướng dẫn Elisp, nút Chức năng là gì :

Bạn có thể sử dụng hàm functionpđể kiểm tra xem một đối tượng có phải là hàm không:

- Hàm: đối tượng hàm Hàm này trả về tnếu ĐỐI TƯỢNG là bất kỳ loại hàm nào, nghĩa là có thể được truyền vào funcall. Lưu ý rằng functionptrả về tcác ký hiệu là tên hàm và trả về 'nil' cho các dạng đặc biệt.


(Man, tôi ghét xoăn-trích dẫn trong sách hướng dẫn. Làm cho tôi thay thế mỗi người trong số họ có mới `sau khi dán từ hướng dẫn ở đây. Hai lần càng nhiều nỗ lực như khi hướng dẫn (sanely) được sử dụng `...'thay vì ‘...’.)


1

Một chức năng là gì?

Để hiểu tại sao điều này xảy ra, chúng ta cần biết chức năng là gì. Khi đánh giá dạng lisp (myfunc arg1 arg2 ...), trước tiên emacs kiểm tra xem đó myfunclà gì . Nếu nó là một chức năng, emacs đánh giá tất cả các hình thức lisp arg1, arg2vv sau đó gọi hàm myfuncvới kết quả là các đối tượng nói ngọng như các đối số.

Như đã lưu ý, andkhông phải là một hàm, nó là một dạng đặc biệt, do đó nó có thể đánh giá các đối số của nó khi cần thiết. Như tôi đã đưa ra trong một nhận xét trước đó, hình thức (and nil (drop 'bomb))này là an toàn vì (drop 'bomb)không bao giờ được đánh giá.

Mặt khác, (apply #'and (list nil (drop 'bomb)))không an toàn, vì apply một hàm, do đó, trước tiên emacs đánh giá #'and(kết quả là một ký hiệu), sau đó đánh giá (list nil (drop 'bomb)), lại là một lệnh gọi hàm, vì vậy bạn đoán điều gì xảy ra tiếp theo: nilđược đánh giá, sau đó (drop 'bomb)được đánh giá.

Tại sao lại applyphàn nàn?

Cố gắng sử dụng applytrên một hình thức đặc biệt (hoặc một macro) không có ý nghĩa gì, bởi vì hình thức đặc biệt không thể có hành vi đặc biệt của nó, vì vậy nó gây ra lỗi.

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.