Lisp:TAGBODY问题

时间:2016-12-13 13:53:23

标签: lisp common-lisp

我是LISP编程的初学者,我不确定如何使用tagbody从键盘读取数字,直到我达到负数。我试图在网上找到可用的资源,但到目前为止我没有成功。

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:8)

tagbody是一个非常低级别的设施。

改为使用doloop

(loop for num = (read) while (plusp num) collect num)

PS。编译器可能会将我的代码宏扩展为tagbody,类似于另一个答案中的表单。在某种程度上,tagbody是Lisp的“汇编”: - )

答案 1 :(得分:3)

接近TAGBODY及其朋友PROG的好方法是将您的算法视为有限状态机。您的函数尝试实现以下内容:

enter image description here

您可以编写以下内容来实现状态机:

(PROG* (N (E (CONS NIL NIL)) (Q (CONS E E)))
   READ-NUMBER
     (SETQ N (READ))
     (IF (MINUSP N)
         (GO FINISH)
         (GO COLLECT))
   COLLECT
     (RPLACD Q (CDR (RPLACD (CDR Q) (CONS N NIL))))
     (GO READ-NUMBER)
   FINISH
     (RETURN (CDAR Q)))

我提升了所有符号并使用了CAR / CDAR / ...因为像TAGBODY / PROG一样,这属于几十年前不再流行的编程风格。 大量有用的状态机已经被LOOP或其他迭代器抽象掉了。话虽如此,TAGBODY仍然可用,并且可能在极少数情况下有用,隐藏在宏后面。

Graphviz源码
digraph abc {

rankdir=LR
nodesep=1

R[label="READ NUMBER"]
C[label="COLLECT"]
F[label="FINISH", penwidth=2]

I[style=invis, width=0]
I -> R [penwidth=0, arrowhead="vee"]

R -> C [label="N ≥ 0"]
C -> R [label="TRUE"]
R -> F [label="N < 0"]

}