解决了
我有类似于这四个功能的东西:base、init、func和some。func是递归的,并调用它自己:在“停止情况”中,它将调用some并返回其值,然后如果将控制返回到"init",则从“init”调用该控件;后者一旦从base调用即可。
base
-> init
-> func
-> init
-> func
-> some
|
_________+
|
v
; should continue from here (in `func`)不再是了
相反,在第一次调用some之后,控件直接交给base,跳过了我期望的中间(init,func)对调用。
实际上,我使用block、return和递归(例如“互尾递归factorial")尝试了几种更简单的案例,它们都运行得很好。我提到func使用了一个test助手函数,即catch a throw (但我甚至尝试了一个使用(catch 'test (throw 'test 0))的例子,而且它是可以的);所以不管我的真正的程序有什么引起问题的东西。
这是elisp:每个defun都以block开头,所有函数都使用return,如下所示。
"**defun**/**block**“[我从使用"**defun***"]改为使用
(defmacro 4+ (number)
"Add 4 to NUMBER, where NUMBER is a number."
(list 'setq number (list '1+ (list '1+ (list '1+ (list '1+ number))))))
(defmacro 4- (number)
"Subtract 4 from NUMBER, where NUMBER is a number."
(list 'setq number (list '1- (list '1- (list '1- (list '1- number))))))
(defun mesg (s &optional o)
"Use ATAB to tabulate message S at 4-multiple column; next/prev tab if O=1/0."
(when (null o) (setq o 0))
(case o (0 (4- atab)) (1 nil))
(message (concat "%" (format "%d" (+ atab (length s))) "s") s)
(case o (0 nil) (1 (4+ atab))))
(defun* base ()
(let (pack)
(setq atab 0)
(mesg "base->" 1)
(setq pack (init))
(mesg "<-base")))
(defun* init ()
(mesg "init->" 1)
(return-from init (progn (setq temp (func)) (mesg "<-init") temp)))
(defun* func (&optional pack)
(mesg "func->" 1)
(when (not (null pack)) (return-from func (progn (mesg "<+func") pack)))
(when (< 0 (mod (random) 2)); stop case
(return-from func (progn (setq temp (some)) (mesg "<-func") temp)))
(setq pack (init))
(case (mod (random) 2)
(0 (return-from func (progn (mesg "<0func") pack)))
(1 (return-from func (progn (setq temp (func pack)) (mesg "<1func") temp))) ; use tail-recursion instead of `while'
(t (error "foo bar"))))
(defun* some ()
(mesg "some->" 1)
(return-from some (progn (mesg "<-some") (list 2 3 4))))
(base)pack变量是我的值-list作为数据结构。我还使用func (在尾递归调用中)使用一个特殊的累积参数来重申自己,以避免“命令式”while。
因此,与我所期望的不同(每个>都由<配对)
base->
init->
func->
init->
func->
some->
<-some
<-func
<-init
func-> ; tail-recursion
<+func
<1func
<-init
<-base我的程序表现如下。
base
-> init
-> func
-> init
-> func
-> some
|
__________________________+
|
v
; control yielded here (to `base`)不再是了
为什么控制产生的太快回到程序的开始,而不继续在第一次调用func,之后return从第二个调用通过init
感谢你的帮助,
塞巴斯蒂安
发布于 2012-12-17 20:40:00
看看您的代码,我不清楚func中的块有多大。如果块包含整个func定义,那么是的,控件在返回时到达func,但是块被完全跳过,因此函数完全跳过,并一直返回到调用它的地方(最终是base)。可能是这样吗?
如果是这样的话,您必须将要执行的代码放在块后返回之后。
编辑:再次查看您的代码,我认为您没有使用return,因为应该使用它。例如,在init中
(block nil
...
(return (func ...)))这个return“取消”了块,并产生了与根本没有块相同的效果,除非在"...“中调用的某些函数确实有一个没有block的return。因此,这里的return取消了func可能的返回点。
发布于 2012-12-20 13:58:48
谢谢您的回答:在我的程序中插入我尝试过的那些消息,就像我添加的解释代码一样,显示了elisp没有elisp问题,但是我在设计上有些地方错了。
https://stackoverflow.com/questions/13913551
复制相似问题