수색…


통사론

  • macroexpand 예제에서 사용 된 ' 기호는 quote 연산자에 대한 구문 식 설탕입니다. 대신에 (macroexpand (quote (infix 1 + 2))) 를 쓸 수 있습니다.

비고

매크로는 컴파일 타임, 즉 read-eval-print-loopeval 단계에서 실행되는 함수 일뿐입니다.

리더 매크로는 컴파일 타임이 아닌 읽기 시간에 확장되는 또 다른 형태의 매크로입니다.

매크로를 정의 할 때 가장 좋은 방법입니다.

  • 알파 - 이름 바꾸기, 매크로가 확장 바인딩 이름 충돌이 발생할 수 있기 때문에. 바인딩 충돌은 매크로를 사용할 때 해결하기가 쉽지 않습니다. 매크로가 범위에 바인딩을 추가 할 때마다 각 기호의 끝에 # 기호를 사용해야합니다.

단순 중위 매크로

Clojure는 다음과 같은 접두사 표기법을 사용합니다. 연산자는 피연산자보다 먼저옵니다.

예를 들어 두 숫자의 단순한 합계는 다음과 같습니다.

(+ 1 2)
;; => 3

매크로를 사용하면 Clojure 언어를 어느 정도 조작 할 수 있습니다. 예를 들어, 중도 표기법 (예 : 1 + 2 )으로 코드를 작성할 수있는 매크로를 구현할 수 있습니다.

(defmacro infix [first-operand operator second-operand]
    "Converts an infix expression into a prefix expression"
    (list operator first-operand second-operand))

위 코드가하는 일을 분해 해 봅시다.

  • defmacro 는 매크로를 정의 할 때 사용하는 특별한 형식 입니다.
  • infix 는 정의하고있는 매크로의 이름입니다.
  • [first-operand operator second-operand] 는이 매크로가 호출 될 때받을 것으로 예상되는 매개 변수입니다.
  • (list operator first-operand second-operand) 는 매크로의 본문입니다. 그것은 단순히 infix 매크로에 제공된 매개 변수의 값을 가진 list 를 생성하고 그것을 반환합니다.

defmacro 는 다른 Clojure 구문과 약간 다르게 동작하기 때문에 특수한 형식 입니다. 매크로를 호출 할 때 매개 변수가 즉시 평가되지 않습니다. 이것이 우리가 다음과 같이 쓸 수있게 해줍니다 :

(infix 1 + 2)
;; => 3

infix 매크로는 1 + 2 인수를 (+ 1 2) 로 확장합니다. 이는 유효한 Clojure 형식이며 평가할 수 있습니다.

infix 매크로가 생성하는 것을보고 싶다면 macroexpand 연산자를 사용할 수 있습니다.

(macroexpand '(infix 1 + 2))
;; => (+ 1 2)

macroexpand 는 이름에서 알 수 있듯이 매크로를 확장합니다 (이 경우 1 + 2(+ 1 2) 로 변환하기 위해 infix 매크로를 사용하지만 매크로 확장의 결과는 Clojure의 통역관.

구문 인용 부호와 인용 부호 해제

표준 라이브러리의 예제 ( core.clj : 807 ) :

(defmacro and
  "Evaluates exprs one at a time, from left to right. If a form
  returns logical false (nil or false), and returns that value and
  doesn't evaluate any of the other expressions, otherwise it returns
  the value of the last expr. (and) returns true."
  {:added "1.0"}
  ([] true)
  ([x] x)
  ([x & next]
   `(let [and# ~x]
      (if and# (and ~@next) and#))))
  • ` syntax-quote라고하는 것은 (quote) 와 같지만 재귀 적입니다 : 매크로 확장 중에는 (let …) , (if …) 등은 평가하지 않고 그대로 출력합니다
  • ~ 일명 unquote는 구문 인용 형식 내에서 단일 형식에 대한 구문 인용 부호를 취소합니다. 그래서 x 값은 매크로를 확장 할 때 출력됩니다 ( x 기호를 출력하는 대신)
  • ~@ aka unquote-splicing은 unquote와 같지만 목록 인수를 취하여 양식을 구분하는 각 목록 항목을 확장합니다.
  • # 이름 충돌을 막기 위해 기호에 고유 ID를 추가합니다. 너무, 구문 인용 표현 내부의 동일한 기호에 대해 동일한 ID를 추가 and# 내부 letand#if 같은 이름을 얻을 것이다


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow