문제

나는 계속 노력해왔어 실용적인 커먼 리스프 연습으로 숫자가 다른 숫자의 배수인지 확인하는 매크로를 작성하기로 결정했습니다.

(defmacro multp (value factor)
`(= (rem ,value ,factor) 0))

하도록 하다 :(multp 40 10)반면에 true로 평가됩니다.(multp 40 13)하지 않습니다

문제는 이 매크로가 작동하는가입니다. 새다 어떤 면에서는?또한 이것이 "좋은" Lisp입니까?사용할 수 있는 기존 함수/매크로가 이미 있습니까?

도움이 되었습니까?

해결책

Siebel은 가능한 누수 원인에 대한 광범위한 요약(어차피 간단한 경우)을 제공하지만 여기에는 해당 내용이 없습니다.둘 다 value 그리고 factor 한 번만 순서대로 평가됩니다. rem 부작용이 없습니다.

하지만 이는 좋은 Lisp가 아닙니다. 이 경우에는 매크로를 사용할 이유가 없기 때문입니다.기능

(defun multp (value factor)
  (zerop (rem value factor)))

모든 실제적인 목적에 있어서 동일합니다.(사용에 주의하세요. zerop.이 경우 상황이 더 명확해진다고 생각하지만 강조해야 할 경우 테스트 중인 값이 0이 아닌 다른 값이면 여전히 의미가 있을 수 있다는 점을 강조해야 합니다. (= ... 0) 더 나을 수도 있음)

다른 팁

매크로가 괜찮아 보이는데요.나는 누출 매크로가 무엇인지 모르지만 귀하의 매크로는 매우 간단하며 어떤 젠심도 필요하지 않습니다.이것이 "좋은" Lisp인 한, 내 경험 법칙은 함수가 작동하지 않을 때만 매크로를 사용하는 것이며, 이 경우 매크로 대신 함수를 사용할 수 있습니다.하지만 이 솔루션이 효과가 있다면 사용하지 않을 이유가 없습니다.

원칙적으로 사용자는 다음을 수행할 수 있습니다.

(flet ((= (&rest args) nil))
  (multp 40 10))

NIL로 평가됩니다 ...단, ANSI CL에서는 CL:=을 포함한 대부분의 표준 기호를 다시 바인딩하는 것을 불법으로 규정하므로 이 특별한 경우에는 안전합니다.

물론 일반적으로 참조 비투명성(매크로가 확장된 컨텍스트에서 식별자 캡처)과 매크로 비위생적(확장된 코드에 식별자 유출)을 모두 알고 있어야 합니다.

아니요, 매크로의 "어휘적 폐쇄"에 도입된 기호는 외부로 공개되지 않습니다.

실수로 누출이 거의 항상 발생하더라도 누출이 반드시 나쁜 것은 아닙니다.제가 작업한 한 프로젝트에서 다음과 유사한 매크로가 유용하다는 것을 알았습니다.

(defmacro ana-and (&rest forms)
  (loop for form in (reverse forms)
        for completion = form then `(let ((it ,form))
                                      (when it
                                       ,completion))
        finally (return completion)))

이를 통해 시퀀스의 이전 호출에서 전달된 인수(그리고 NIL을 반환하여 실패 신호를 표시함)를 사용하여 순차적으로 수행해야 하는 작업을 "단락"시킬 수 있었습니다.이 코드의 특정 컨텍스트는 파서 생성기를 사용하여 적절한 파서를 작성하는 것이 수동으로 롤링하는 것보다 더 많은 작업이라는 충분히 잘 짜여진 구문이 있는 구성 파일에 대해 손으로 작성한 파서를 위한 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top