【问题标题】:Why does 'rutils.iter' seem to work differently than 'iterate'?为什么“rutils.iter”的工作方式似乎与“迭代”不同?
【发布时间】:2016-11-01 01:11:29
【问题描述】:

(我知道这可能是特定于库的,在这种情况下,请随时关闭它,我问的是如果原因是特定于语言的)

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)))

(它给出了关于所有未定义的错误......为什么?)

我试过macroexpanding 他们每个人,这就是我看到的:

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

(显然第二个版本“半途而废”有效,而不是什么都不做

有什么提示吗?提前致谢!

【问题讨论】:

  • 使用关键字作为句法标识符
  • 是的,下面的作品! ``` CL-USER> (rutilsx.iter:iter (:for el :in num-list) (when (>= el 3) (:collect el))) ``` 但是 (1) 它不起作用当我使用:when而不是when时,以及(2)更一般的情况下,为什么iterate对应的版本没有这个问题?
  • 如果您阅读 source file 顶部的 cmets,它表示标识符只允许使用关键字。 WHEN 是常规的 CL 宏,所以它不应该是关键字。
  • 对,我应该有 RTFM,抱歉;感谢您指出这一点。

标签: loops common-lisp


【解决方案1】:

关键字

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

何时

WHEN 不是 ITERATE 语法标识符。它是通常的 Common Lisp cl:when。因此你不能使用关键字:when

ITERATE 子句可以在 Lisp 表单中

对于那些习惯于 LOOP 的人来说,有点令人惊讶的是,ITERATE 宏允许在 Lisp 表达式中使用像 COLLECT 这样的子句。

循环:

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

以上需要WHEN ...LOOP 宏的子句。

迭代:

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

在上面的形式中,WHEN 是普通的CL:WHEN,而iterate 到它的子形式中,当它查找子句时,例如本例中的collect

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-04
    • 2018-02-23
    • 1970-01-01
    相关资源
    最近更新 更多