2016-11-01 2 views
1

'rutils.iter'가 'iterate'와 다르게 작동하는 이유는 무엇입니까?

모두 rutilsx.iteriterate 라이브러리 (나는 이유는 언어 별이다 나는 경우 부탁 해요, 그 경우는 그것을 폐쇄 부담이 도서관 고유의 것으로 판명 수 이해() Quicklisp을 통해 사용 가능)는 동일한 "Don't Loop, Iterate" 라이브러리를 제공하는 것으로 보입니다.

그러나 후자는 "그냥 효과가 있지만"전자는 그렇지 않습니다. 나는 내가 여기서 무엇인가 잘못하고 있다고 확신한다. 나는 무엇을 모르 느냐.

CL-USER> num-list 
(1 2 3 4 5 6 7 8 9) 

CL-USER> (iter (for el in num-list) 
       (when (>= el 3) 
       (collect el))) 
(3 4 5 6 7 8 9) 

을하지만 그렇지 않은 :

그래서이 작품

CL-USER> (rutilsx.iter:iter (for el in num-list) 
       (when (>= el 3) 
       (collect el))) 

(? 모든 약이주는 오류가 정의되어 있지 않다고 ... 왜)

나는 보내고 macroexpand 시도 각각은 내가 본 것입니다 :

CL-USER> (macroexpand '(iter (for el in num-list) 
       (when (>= el 3) 
       (collect el)))) 
(LET* ((#:LIST21 NIL) 
     (EL NIL) 
     (#:RESULT20 NIL) 
     (#:END-POINTER22 NIL) 
     (#:TEMP23 NIL)) 
    (BLOCK NIL 
    (TAGBODY 
     (PROGN (SETQ #:LIST21 NUM-LIST)) 
    LOOP-TOP-NIL 
     (PROGN 
     (IF (ENDP #:LIST21) 
      (GO LOOP-END-NIL)) 
     (SETQ EL (CAR #:LIST21)) 
     (SETQ #:LIST21 (CDR #:LIST21)) 
     (IF (>= EL 3) 
      (PROGN 
      (PROGN 
      (SETQ #:TEMP23 (LIST EL)) 
      (SETQ #:END-POINTER22 
        (IF #:RESULT20 
         (SETF (CDR #:END-POINTER22) #:TEMP23) 
         (SETQ #:RESULT20 #:TEMP23))) 
      #:RESULT20)) 
      NIL)) 
     (PROGN) 
     (GO LOOP-TOP-NIL) 
    LOOP-END-NIL 
     (PROGN)) 
    #:RESULT20)) 
T 

CL-USER> (macroexpand '(rutilsx.iter:iter (for el in num-list) 
       (when (>= el 3) 
       (collect el)))) 
(LET*() 
    (BLOCK NIL 
    (TAGBODY 
    LOOP-TOP-NIL 
     (FOR EL IN NUM-LIST) 
     (IF (>= EL 3) 
      (PROGN (COLLECT EL)) 
      NIL) 
     (GO LOOP-TOP-NIL)) 
    NIL)) 
T 

어떤 힌트 (분명히 두 번째 버전 "반 방법은"대신 아무것도을하고하지의 작품)? 미리 감사드립니다!

+0

구문 식별자에 키워드 사용 –

+0

예, 다음 작동합니다! '' CL-USER> (rutilsx.iter : ITER (엘 님) 납입리스트 (경우 (> = 3 EL) (:)) EL 수집) '' 하지만 (1)'when' 대신'when :'을 사용할 때 작동하지 않으며, (2)보다 일반적으로'iterate '를 가진 해당 버전에이 문제가 없었던 이유는 무엇입니까? – agam

+1

[소스 파일] (https://github.com/vseloved/rutils/blob/master/contrib/iter.lisp) 맨 위의 주석을 읽으면 식별자에만 키워드가 허용된다고 말합니다. 'WHEN'은 일반적인 CL 매크로이므로 키워드가 아니어야합니다. – jkiiski

답변

2

키워드

rutilsx.iter 라이브러리는 ITERATE의 구문 식별자에 대한 키워드를 사용합니다.

WHENITERATE 구문 론적 식별자 없다

. 일반적인 Common Lisp cl:when입니다. 따라서 :when 키워드를 사용할 수 없습니다. 리스프는 LOOP에 사용되는 사람들을 위해 조금 놀라운 무엇

을 형성하고 내부에

ITERATE 조항은 ITERATE 매크로는 리스프 식 내부 COLLECT 같은 조항을 허용 할 수 있습니다.

LOOP :

(loop for el in '(1 2 3 4 5 6 1 2 3) 
     when (>= el 3) 
     collect el) 

위는 LOOP 매크로의 조항으로 WHEN ...이 필요합니다.

ITERATE :이 예에서 collect 같은 절 찾는다 때 상기 형태에있어서

(iter (for el in num-list) 
     (when (>= el 3) 
     (collect el))) 

, WHEN는 통상 CL:WHEN 및 하위 폼에 iterate걸어 매크로이다.

관련 문제