나는 Common Lisp을 Practical Common Lisp에서 배우고있다.Common Lisp에서 비슷한 기능을 작성하는 방법은 무엇입니까?
(defun read-u2 (in)
(+ (* (read-byte in) 256) (read-byte in)))
내가 마찬가지로 이진수의 다른 종류를 읽는 기능을 쓸 수 있습니다 : 그것은 읽고 여기에 하나의 예제 제 24 장에서 바이너리 파일을 작성하기위한 헬퍼 함수의 예를 가지고있다. 그러나 그렇게하는 것은 DRY 원리를 위반한다고 생각했습니다. 게다가,이 함수들은 비슷할 것이므로, 매크로로 함수를 생성하려고했습니다.
(defmacro make-read (n be)
`(defun ,(intern (format nil "READ~d~:[L~;B~]E" n be))
(&optional (stream *standard-input*))
(logior ,@(loop for i from 0 below n collect
`(ash (read-byte stream)
,(* 8 (if be (- n 1 i) i)))))))
(defmacro make-read-s (n be)
`(defun ,(intern (format nil "READ~d~:[L~;B~]E-S" n be))
(&optional (stream *standard-input*))
(let ((a (,(intern (format nil "READ~d~:[L~;B~]E" n be)) stream)))
(if (zerop (logand a ,(ash 1 (1- (* 8 n)))))
a
(logior a ,(ash -1 (* 8 n)))))))
(defmacro make-write (n be)
`(defun ,(intern (format nil "WRITE~d~:[L~;B~]E" n be))
(n &optional (stream *standard-output*))
(setf n (logand n ,(1- (ash 1 (* 8 n)))))
,@(loop for i from 0 below n collect
`(write-byte (ldb (byte 8 ,(* 8 (if be (- n 1 i) i))) n)
stream))))
(eval-when (:compile-toplevel :load-toplevel :execute)
(dolist (cat '("READ" "READ-S" "WRITE"))
(dolist (be '(nil t))
(dolist (n '(1 2 4 8))
(eval `(,(intern (format nil "MAKE-~a" cat)) ,n ,be))))))
작동합니다. 1, 2, 4, 8 크기의 부호없는 부호있는 정수를 읽고 쓸 수있는 함수를 생성합니다. SLIME은 그것을 이해합니다. 그러나 더 좋은 방법이 있는지 궁금합니다.
Common Lisp에서 비슷한 기능을 많이 작성하는 가장 좋은 방법은 무엇입니까?
왜 '& optional'을 사용하지 않으시겠습니까? 효율성을 위해 필요한 경우 함수가 인라인 된 경우에도 적용됩니까? – nisekgao
@nisekgao : 내 편집 참조. –