Scheme 매크로를 어떤 용도로 사용하셨나요?[닫은]
문제
매크로의 많은 예는 람다를 숨기는 것에 관한 것 같습니다.CL의 파일 열기 포함.저는 특히 PLT Scheme에서 좀 더 이국적인 매크로 사용 방법을 찾고 있습니다.매크로 사용과 매크로 사용을 언제 고려해야 하는지 알고 싶습니다.기능을 사용합니다.
해결책
나는 체계 매크로 만 사용합니다 (define-syntax
) 더 나은 람다 구문과 같은 작은 것들 :
(define-syntax [: x]
(syntax-case x ()
([src-: e es ...]
(syntax-case (datum->syntax-object #'src-: '_) ()
(_ #'(lambda (_) (e es ...)))))))
당신이 쓸 수 있습니다
[: / _ 2] ; <-- much better than (lambda (x) (/ x 2))
Dan Friedman은 매크로를 사용하여 OO의 마인드 벤딩 구현을 가지고 있습니다. http://www.cs.indiana.edu/~dfried/ooo.pdf
그러나 솔직히, 모든 것 유용한 내가 정의한 매크로는 도난당했습니다 Paul Graham 's on Lisp 일반적으로 글을 쓰는 것이 더 쉽습니다 defmacro
(define-macro
PLT 체계에서). 예를 들어, aif
꽤 못 생겼다 define-syntax
.
(define-syntax (aif x)
(syntax-case x ()
[(src-aif test then else)
(syntax-case (datum->syntax-object (syntax src-aif) '_) ()
[_ (syntax (let ([_ test]) (if (and _ (not (null? _))) then else)))])]))
define-syntax
변수를 캡처 할 수 없다는 것을 기쁘게 생각하는 매우 간단한 매크로에는 사용하기 쉽다는 점에서 이상합니다. 그리고 변수를 캡처 할 수 없어서 매우 복잡한 매크로 DSL 용이하게. 첫 번째 경우에 당신은 그것에 대해 생각하지 않고 코드를 작성하려고합니다. 두 번째 경우에는 DSL에 대해 충분히 생각했을 것입니다. syntax-rules
/syntax-case
신비한 버그를 피하기위한 체계가 아닌 언어.
그러나 나는 계획에 그다지 매크로를 사용하지 않습니다. 관용 체계는 너무 기능적이어서 여러 번 기능 프로그램을 작성하고 몇 개의 람다를 숨기고 싶어합니다. 나는 기능 열차를 탔고 이제 당신이 Lambda에 대한 게으른 언어 나 좋은 구문을 가지고 있다면 필요하지 않기 때문에 매크로가 순전히 기능적인 스타일에 유용하지는 않다고 믿습니다.
그래서 추천합니다 실용적인 공통 LISP 그리고 LISP에서. PLT 구성표를 사용하려면 대부분의 defmacro
매크로는 함께 작동합니다 define-macro
. 또는 일반적인 LISP를 사용하십시오.
다른 팁
새로운 제어 구조와 새로운 바인딩 구조물을 구현하려면 매크로가 필요합니다.
따라서 이러한 종류의 구성을 찾으십시오 http://planet.plt-scheme.org. Planet에서는 문서와 코드를 탐색합니다.
새로운 제어 구조에 대한 예 :
http://planet.plt-scheme.org/package-source/soegaard/control.plt/2/0/planet-docs/manual/index.html
새로운 바인딩 형태의 예를 찾으려면 "With-"로 시작하는 매크로를 찾으십시오. 유용한 예 중 하나는 행성에서 Math.plt에서도 발견됩니다.
; Within a (with-modulus n form1 ...) the return values of
; the arithmetival operations +, -, * and ^ are automatically
; reduced modulo n. Furthermore (mod x)=(modulo x n) and
; (inv x)=(inverse x n).
; Example: (with-modulus 3 (^ 2 4)) ==> 1
(define-syntax (with-modulus stx)
(syntax-case stx ()
[(with-modulus e form ...)
(with-syntax ([+ (datum->syntax-object (syntax with-modulus) '+)]
[- (datum->syntax-object (syntax with-modulus) '-)]
[* (datum->syntax-object (syntax with-modulus) '*)]
[^ (datum->syntax-object (syntax with-modulus) '^)]
[mod (datum->syntax-object (syntax with-modulus) 'mod)]
[inv (datum->syntax-object (syntax with-modulus) 'inv)])
(syntax (let* ([n e]
[mod (lambda (x) (modulo x n))]
[inv (lambda (x) (inverse x n))]
[+ (compose mod +)]
[- (compose mod -)]
[* (compose mod *)]
[square (lambda (x) (* x x))]
[^ (rec ^ (lambda (a b)
(cond
[(= b 0) 1]
[(even? b) (square (^ a (/ b 2)))]
[else (* a (^ a (sub1 b)))])))])
form ...)))]))
마지막 질문에 대한 답변을 시작하겠습니다.함수 대신 매크로를 사용해야 하는 경우매크로는 함수가 할 수 없는 일을 하고, 함수는 매크로가 할 수 없는 일을 하기 때문에 혼합하기는 힘들겠지만 좀 더 자세히 살펴보겠습니다.
인수를 평가하려면 함수를 사용하고, 인수를 평가하지 않으려면 매크로를 사용합니다.별로 유용하지 않죠?무언가를 다른 방식으로 작성하고 싶을 때, 패턴을 보고 추상화하고 싶을 때 매크로를 사용합니다.예를 들어:나는 foo의 다양한 값과 유일한 변경 사항이 foo인 유사한 본문에 대해 foo-create, foo-process 및 foo-destroy라는 세 가지 함수를 정의합니다.패턴은 있지만 함수에 비해 수준이 너무 높아서 매크로를 만듭니다.
내 경험에 따르면 Scheme의 매크로는 Common Lisp 또는 Common Lisp와 같은 다른 Lisps와 마찬가지로 많이 사용됩니다. 클로저.나는 이것이 아마도 위생적인 매크로가 그렇게 좋은 생각이 아니라는 증거라고 생각하며, 여기서 나는 그 이유에 대해 Paul Graham의 의견에 동의하지 않을 것입니다.때로는 더러워지고 싶기 때문이 아니라(비위생적) 위생적인 매크로가 결국 복잡해지기 때문입니다.
Peter Seibel의 실용적인 공통 LISP는 매크로에 대한 좋은 소개를 가지고 있습니다. Paul Graham의 LISP에서는 더 복잡한 사례의 좋은 근원 일 수 있습니다. 또한 공통 LISP의 내장 매크로를 살펴보십시오.
그만큼 매크로를 통한 오토마타 이 논문은 체계에서 매크로를 통해 유한 상태 기계를 구현하는 기능적 프로그래밍 펄을 제시합니다.
그 책 합리적인 계획서 이 책에 사용 된 논리 프로그래밍 언어 인 Minikanren의 완전한 거시적 구현으로 끝납니다. 이 종이 Minikanren과 그 구현을 책보다 공식적으로 그리고 간결하게 제시합니다.
변장에서 람다 형태가 아닌 고급 매크로의 예는 일반적인 LISP의 매크로입니다. 슬롯과 함께, 객체 슬롯 액세스가 일반 변수 액세스처럼 보이게합니다.
(with-slots (state door) car
(when (eq state :stopped)
(setq state :driving-around)
(setq door :closed)))
이것은 슬롯 값을 로컬 변수에 바인딩하고 그와 같이 액세스하는 것과 동일하지 않습니다. 슬롯과 함께 SETQ를 통해 슬롯을 변경하고 외부 변경을 즉시 볼 수 있습니다.
나는 가졌다 curry
내가 손바닥에 많은 계획을 세웠을 때 매크로. 꽤 편리했습니다.
체계 매크로를 사용하면 원래 언어 저자가 스스로 포함하지 않았다는 기능을 추가 할 수 있습니다. 그것이 매크로의 전체 철학입니다.
다음은 작은 예입니다. PLT 체계는 슬라이드 쇼 (Slideshow)라는 프레젠테이션을 작성하는 언어를 제공합니다. 매크로를 사용하여 슬라이드 번호를 슬라이드와 연결하여 더 쉽게 관리 할 수있었습니다.
Infix 구문을 제공하는 매크로를 작성했습니다. 너무 멋진 것은 없습니다. 우선 순위가 없습니다. Prefix 구문은 일반적으로 괜찮지 만 <and>에 대한 Infix를 선호합니다.
절차로 충분하지 않을 때 나는 그것들을 사용합니다.