Writing macros requires an extra degree of caution

매크로 작성은 상당한 주의가 필요함.

A function is isolated in its own lexical world, but a macro, because it is expanded into the calling code, can give the user an unpleasant surprise unless it is carefully written.

함수 자체는 lexcial world에서 격리 되지만 매크로는 호출 코드로 확장되므로 주의 깊게 작성되지 않으면 사용자에게 불쾌한 놀라움을 줄 수 있다.

Chapter 9 explained variable capture, the biggest such surprise.

9장에서는 변수캡처로 설명함.

This chapter discusses four more problems to avoid when defining macros.

이번 장에서는 매크로를 정의할 때 피해야할 4가지 문제를 설명함.

10.1 Number of Evaluations

Several incorrect versions of for appeared in the previous chapter. Figure 10.1 shows two more, accompanied by a correct version for comparison.

이전 장에서 여러 잘못된 버전이 나타났습니다. 그림 10.1는 비교를 위해 옳은 버전하고 아닌 버전 2개를 보여줌

; A correct version:
(defmacro for ((var start stop) &body body)
	(let ((gstop (gensym)))
		`(do ((,var ,start (1+ ,var))
					(,gstop ,stop))
				 ((> ,var ,gstop))
				,@body)))

캡처링 문제는 없지만 여러번 평가하는 버그
Subject to multiple evaluations:

(defmacro for ((var start stop) &body body)
	`(do ((,var ,start (1+ ,var)))
			 ((> ,var ,stop)) ;;여기에서 사이드이팩트가 여러번 평가됨.
			,@body))

잘못된 평가 순서 
Incorrect order of evaluation:

(defmacro for ((var start stop) &body body)
	(let ((gstop (gensym)))
		`(do ((,gstop ,stop)
					(,var ,start (1+ ,var)))
				 ((> ,var ,gstop))
			 ,@body)))

Figure 10.1: Controlling argument evaluation.

Though not vulnerable to capture, the second for contains a bug.

두번째 녀석은 캡처에는 취약하지 않지만 확실히 버그가 있다.

It will generate an expansion in which the form passed as [stop] will be evaluated on each iteration

stop으로 전달된 폼(form)이 각 반복마다 평가되도록 확장한다.

In the best case, this kind of macro is inefficient, repeatedly doing what it could have done just once

가장 좋은 경우, 이런 매크로는 비효율적이다, 한 번만 할 수 있는 일을 반복적으로 수행하니까

If stop has side-effects, the macro could actually produce incorrect results.