为什么' rutils.iter'似乎工作方式与“#ite;”

时间:2016-11-01 01:11:29

标签: loops common-lisp

(我知道这可能会变成特定于图书馆的,在这种情况下可以随意关闭它,我会问,如果原因是特定语言的话)

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

VS

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

(显然第二个版本"中途"有效,而不是没有

任何提示?提前谢谢!

1 个答案:

答案 0 :(得分:2)

<强>关键字

rutilsx.iter库使用ITERATE的句法标识符的关键字。

:当

WHEN不是ITERATE句法标识符。这是通常的Common Lisp cl:when。因此,您无法使用关键字:when

ITERATE子句可以在Lisp表单中

对于习惯LOOP的人来说有点令人惊讶,ITERATE宏允许在Lisp表达式中使用COLLECT之类的子句。

LOOP:

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

以上需要WHEN ...才能成为LOOP宏的一个子句。

ITERATE:

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

在上面的表单中,WHEN是正常的CL:WHEN,而iterate 移动到其子表单中,当它查找子句时,如{{ 1}}在这个例子中。