【发布时间】:2012-12-04 12:18:38
【问题描述】:
[已解决]
这四个函数我有类似的东西:base、init、func 和some。 func 是递归的并调用自身:在 "stop case" 中,它将调用 some 并返回其值,然后它应该将控制权返回给 "@ 987654327@",从中调用它;后者曾被base 调用。
base
-> init
-> func
-> init
-> func
-> some
|
_________+
|
v
; should continue from here (in `func`)
[不再]
相反,在第一次调用some 之后,控制权直接交给base,跳过了我期望的中间(init,func) 对调用。
我实际上使用block、return 和递归(例如,“相互尾递归factorial”)尝试了几个更简单的情况,并且都运行良好。我提到func 使用test 辅助函数catch 和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 用一个特殊的累积参数重申自己(在尾递归调用中),这样我就可以避免 "imperative" 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,在第二次通过init 调用return 之后继续?
感谢任何帮助,
塞巴斯蒂安
【问题讨论】:
-
对不起,我现在输入
some。 -
@Stefan:换句话说,是否有一些以前遇到过的函数/部分/问题已知的[e]lisp可能最少 i> 与
block/return技术交互? (即函数string-match...?)。我在公共存储库中有代码,但最终我只有 20%,它与解析LaTeX代码行有关。