Tôi đã định nghĩa một số hàm đơn giản trong init.el, ví dụ my-cache-file
:
(defconst my-cache-directory
(expand-file-name ".cache" user-emacs-directory)) ; ~/.emacs/.cache
(defun my-cache-file (x)
(expand-file-name x my-cache-directory)) ; ~/.emacs/.cache/x
(setq savehist-file
(my-cache-file "savehist"))
(setq backup-directory-alist
`(("." . ,(my-cache-file "backups/"))))
Đây có vẻ như là một trường hợp sử dụng tốt cho defsubst
:
(defsubst my-cache-file (x) ...)
Sau đó, tôi bắt đầu học về biên dịch, và muốn tối ưu hóa hơn nữa. Tôi ngây thơ cố gắng:
(defsubst my-cache-file (x)
(eval-when-compile (expand-file-name x my-cache-directory)))
nhưng trình biên dịch đã phàn nàn (đúng) về biến miễn phí x
, vì vậy thay vào đó tôi gói mã gọi:
(setq savehist-file
(eval-when-compile (my-cache-file "savehist")))
(setq backup-directory-alist
`(("." . ,((eval-when-compile (my-cache-file "backups/"))))
Tuy nhiên, người gọi cuối cùng có lẽ nên đánh giá toàn bộ thời gian biên dịch, vì vậy tôi đã kéo eval-when-compile
lên:
(setq backup-directory-alist
(eval-when-compile `(("." . ,(my-cache-file "backups/")))))
Tôi muốn tránh xả rác mã của mình với nhiều eval-when-compile
cuộc gọi hơn mức cần thiết và tôi tự hỏi liệu có cách tiếp cận nào tốt hơn tôi có thể sử dụng macro hay không define-inline
. Các tài liệu làm cho define-inline
âm thanh đầy hứa hẹn:
Các hàm được xác định thông qua định nghĩa nội tuyến có một số lợi thế đối với các macro được xác định bởi defsubst hoặc defmacro:
- Chúng có thể được truyền cho mapcar (xem Chức năng ánh xạ).
- Họ hiệu quả hơn.
- Chúng có thể được sử dụng làm biểu mẫu địa điểm để lưu trữ các giá trị (xem Biến tổng quát).
- Chúng hoạt động theo cách dễ dự đoán hơn cl-defsubst (xem Danh sách đối số trong Phần mở rộng Lisp chung cho GNU Emacs Lisp).
Nhưng cú pháp có vẻ rườm rà và tôi không thể tìm thấy một ví dụ nào về việc nó được sử dụng ngoài tự nhiên. Tôi cũng không thể tìm thấy bất kỳ lời giải thích nào về tuyên bố rằng defsubst kém hiệu quả hơn.
Có ai đã sử dụng define-inline
, hoặc có một macro khác mà tôi nên xem xét, hoặc tôi chỉ nên gắn bó với defsubst
?
defmacro
hoặcdefine-inline
giải pháp, vì vậy tôi có thể sẽ mất một đâm vào họ. Nó sẽ được tốt đẹp đểeval-when-compile
nướng vào biểu thức kết quả.