2014-11-03 2 views
4

내 일반적인 초점은 Scala와 Lisp/Scheme 매크로이다. 정확히 C/C++/Obj-C의 매크로가 아니다.매크로의 목적은 무엇입니까?

나는 그 점을 보지 못했다.

내가 이해하는 방식은 매크로가 언어를 확장하는 것입니다. 그러나 기능도 마찬가지입니다.

일부 언어 제한으로 인해 일부 기능을 제대로 구현할 수 없으므로 이러한 매크로가 있어야합니다. 그러나 매크로를 사용하여 볼 수있는 많은 예제는 일반적인 함수를 사용하여 구현하는 것이 매우 간단합니다.

그래서 용도가 정확히 무엇입니까? 매크로를 청소하거나 다른 사람이 나를 계몽하시기 바랍니다. 가능한 경우 매크로에서 수행 할 수있는 예제 코드를 제공하십시오. 그러나 일반적인 기능으로는 불가능하거나 어렵습니다.

+0

쓸 수 있도록 http://stackoverflow.com/questions/267862/what-makes

(defmacro with-open-foo ((var &rest options) &body body) '(let ((,var (open-foo ,@options))) (unwind-protect (progn ,@body) (when ,var (close ,var))))) 

: 리스프 개발자는 약간의 매크로를 사용 -lisp-macros-so-special? s = 6 | 1.8097 http://stackoverflow.com/questions/5833033/in-lisp-code-is-data-what-benefit-does-that-provide/5833388?s = 11 | 1.6415 # 5833388 –

+0

http : //stackoverflow.c의 중복 om/questions/2561221/examples-of-what-lisps-macro-use-for-s = 7 | 4.5505 –

답변

7

스칼라 매크로를 사용하여 수행 한 작업에 대한 간략한 요약은 http://scalamacros.org/paperstalks/2014-02-04-WhatAreMacrosGoodFor.pdf입니다. 요약하면, 매크로는 1) 코드 생성, 2) 고급 정적 검사, 3) 도메인 특정 언어에 대한 권한 부여에 도움이되는 것으로 알려져 있습니다. 스칼라에 매크로를 형식 기반으로두면 Lisp와 유사한 언어로 매크로에서 일반적으로 볼 수있는 기능을 강력하고 강력하게 적용 할 수 있습니다.

위에서 링크 된 슬라이드의 일부 예제는 실제로 매크로없이 구현 될 수 있지만 결과는 일부 의미에서 (예 : 성능면에서) 부족하거나 (예 : 중량 오류 메시지로 인해) 사용자에게 지나치게 복잡합니다. 예를 들어, Akka에 대한 유형화 된 채널은 순수 암시로 구현 될 수 있지만 컴파일 속도와 이해 가능성은 떨어집니다. 또는 scala/async는 컴파일러 플러그인으로 구현 될 수 있지만 내부 컴파일러 API에 의존해야하며 배포하기가 더 어려울 수 있습니다.

물론 매크로는 은색 총알이 아닙니다. 분명히 최선의 선택이 아닌 유스 케이스가 있으며 이는 http://scalamacros.org/paperstalks/2014-03-01-MacrosVsTypes.pdf에 개략적으로 나와 있습니다. 궁금한 점은 순수한 매크로 나 매크로없는 솔루션이 아닌 여러 상황에서 신중하게 구성된 하이브리드가 최고가되는 것입니다.

+0

질문을 편집했습니다 –

+0

첫 번째 프레젠테이션에는 몇 가지 예가 있습니다. 1, 2, 5, 7 및 8 매크로없이 구현할 수 있다고 생각하지 않습니다. 3 및 4는 고급 유형 수준 프로그래밍으로 수행 할 수 있지만 결과는 컴파일 타임과 런타임 모두에서 느려지고 유지 관리가 훨씬 어려워집니다. 6은 근사 될 수 있지만 사용자 경험은 어려워 질 것입니다 (오류 메시지, 일치하지 않는 어휘). –

2

Common Lisp와 Scheme에서 대부분의 특수 구문은 실제로 다른 특수 구문, 즉 매크로로 구현됩니다.

예를 들어, Scheme과 CL은 모두 if, condcase입니다. 단 if만이 기본 구문입니다.

표준에 정의 된 매크로와 사용자가 직접 만들 수있는 매크로에 특별한 것은 없습니다. 그것들은 프리미티브처럼 행동하고 작동하도록 만들 수 있습니다.

매크로에는 판독기가 혼란스럽고 놀랄만 한 비용이 있습니다. with-*과 같은 일반적인 명명 규칙을 사용하면 약간의 도움이되지만 함수/프로 시저가 작업을 수행 할 수 있거나 양식을 몇 군데에서만 사용하는 경우에는 매크로를 사용하지 않아야합니다.

+0

질문을 편집했습니다 –

1

매크로 (스칼라 모르는) 리스프에서 사용되는 세 가지 주요 목적이 있습니다

  • 정의 : 뭔가 만들어 직접 해당 장소에 등록되어가. 예 : defun, defgeneric, defclass (표준), deftable (포스트 모더니즘에서).
  • Unwind-protect 래퍼 : 상태가 일시적으로 수정되고 작업 완료 후 수정되도록 보장됩니다. 이것은 반복적으로 쓰는 것이 번거로울 수 있으므로 우리는 속기를 만듭니다. 예 : with-open-file (표준), with-transaction (많은 데이터베이스 라이브러리).
  • 다른 언어의 생성 : 예 : CL-WHO (HTML), Parenscript (JavaScript). Lisp 형식으로 다른 언어의 코드를 생성함으로써, 다른 언어의 코드를 지원하지 않더라도 매크로를 사용할 수 있습니다.

구체 예 :

try (SomeClosable foo = openFoo()) { 
    foo.doSomething(); 
} 

자바 6 만 대략 다음과 같이 표현 될 수있다 :

SomeClosable foo; 
try { 
    foo = openFoo(); 
    foo.doSomething(); 
} finally { 
    if (foo != null && foo.isOpen()) { 
     foo.close(); 
    } 
} 
자바 7 try -blocks에 Closable (S)의 폐쇄를 보장하기위한 약식 소개

Java 개발자는 언어 설계자가이 기능을 구현할 때까지 기다려야했습니다. 그는

(with-open-foo (f :bar baz) 
    (do-some-foo f) 
    (and-something-else)) 

대신

(let ((f (open-foo :bar baz))) 
    (unwind-protect 
     (progn 
     (do-some-foo f) 
     (and-something-else)) 
    (when f (close f)))) 
+0

질문을 편집했습니다 –

+0

@ElectricCoffee : 답변을 편집했습니다. – Svante

+0

'defun'을 사용하여 with-open-foo를 함수로 작성할 수 없습니까? –

관련 문제