Common Lisp中可参数化的返回值

时间:2017-10-28 20:17:05

标签: lisp common-lisp eval block

我在Common lisp中学习了块并做了这个例子来看看块和return-from命令是如何工作的:

 (block b1 
            (print 1)
            (print 2)
            (print 3)
            (block b2 
                   (print 4)
                   (print 5)
                   (return-from b1)
                   (print 6)

               )
            (print 7))

它将按预期打印1,2,3,4和5。将返回值更改为(从b2返回)它将打印1,2,3,4,5和7,正如人们所期望的那样。

然后我尝试将其转换为函数并在返回来自paremetrize标签:

 (defun test-block (arg)  (block b1 
            (print 1)
            (print 2)
            (print 3)
            (block b2 
                   (print 4)
                   (print 5)
                   (return-from (eval arg))
                   (print 6)

               )
            (print 7)))

并使用(test-block' b1)查看它是否有效,但它没有。有没有办法在没有条件的情况下做到这一点?

1 个答案:

答案 0 :(得分:4)

使用条件类似CASE选择要从

返回的块

建议的方法是使用case或类似方法。 Common Lisp不支持块的计算返回。它也不支持计算go s。

使用case条件表达式:

(defun test-block (arg)
  (block b1 
    (print 1)
    (print 2)
    (print 3)
    (block b2 
      (print 4)
      (print 5)
      (case arg
        (b1 (return-from b1))
        (b2 (return-from b2)))
      (print 6))
    (print 7)))

无法从名称中计算词汇go标签,返回块或本地函数

CLTL2谈到go构造的限制:

  

兼容性说明:``计算机去''不支持MacLisp的功能。计算go的语法是特殊的,Lisp Machine Lisp,NIL(Lisp的新实现)或Interlisp不支持该功能。无论如何,计算出的go在MacLisp中很少被使用,并且通过使用case子语句(每个子句执行(非计算)go)来轻松模拟而不会降低效率。

由于goreturn-from等功能是词法范围的构造,因此不支持计算目标。 Common Lisp无法在运行时访问词法环境并查询它们。例如,本地功能也不支持这种功能。在一些词汇环境中,人们不能取名并要求使用该名称的函数对象。

动态替代方案:CATCH和THROW

通常效率较低且动态范围较广的替代方案是catchthrow。在那里计算标签。