首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用块不工作的递归函数返回

使用块不工作的递归函数返回
EN

Stack Overflow用户
提问于 2012-12-17 11:45:01
回答 2查看 138关注 0票数 2

解决了

我有类似于这四个功能的东西:baseinitfuncsomefunc是递归的,并调用它自己:在“停止情况”中,它将调用some并返回其值,然后如果将控制返回到"init",则从“init”调用该控件;后者一旦从base调用即可。

代码语言:javascript
复制
base
  -> init
       -> func
            -> init
                 -> func
                      -> some
                    |
           _________+
          |
          v
          ; should continue from here (in `func`)

不再是

相反,在第一次调用some之后,控件直接交给base,跳过了我期望的中间(init,func)对调用。

实际上,我使用blockreturn和递归(例如“互尾递归factorial")尝试了几种更简单的案例,它们都运行得很好。我提到func使用了一个test助手函数,即catch a throw (但我甚至尝试了一个使用(catch 'test (throw 'test 0))的例子,而且它是可以的);所以不管我的真正的程序有什么引起问题的东西。

这是elisp:每个defun都以block开头,所有函数都使用return,如下所示。

"**defun**/**block**“[我从使用"**defun***"]改为使用

代码语言:javascript
复制
(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

因此,与我所期望的不同(每个>都由<配对)

代码语言:javascript
复制
base->
    init->
        func->
            init->
                func->
                    some->
                    <-some
                <-func
            <-init
            func-> ; tail-recursion
            <+func
        <1func
    <-init
<-base

我的程序表现如下。

代码语言:javascript
复制
base
  -> init
       -> func
            -> init
                 -> func
                      -> some
                           |
 __________________________+
|
v
; control yielded here (to `base`)

不再是了

为什么控制产生的太快回到程序的开始,而不继续在第一次调用func,之后return从第二个调用通过init

感谢你的帮助,

塞巴斯蒂安

EN

回答 2

Stack Overflow用户

发布于 2012-12-17 20:40:00

看看您的代码,我不清楚func中的块有多大。如果块包含整个func定义,那么是的,控件在返回时到达func,但是块被完全跳过,因此函数完全跳过,并一直返回到调用它的地方(最终是base)。可能是这样吗?

如果是这样的话,您必须将要执行的代码放在块后返回之后。

编辑:再次查看您的代码,我认为您没有使用return,因为应该使用它。例如,在init

代码语言:javascript
复制
(block nil
 ...

 (return (func ...)))

这个return“取消”了块,并产生了与根本没有块相同的效果,除非在"...“中调用的某些函数确实有一个没有blockreturn。因此,这里的return取消了func可能的返回点。

票数 1
EN

Stack Overflow用户

发布于 2012-12-20 13:58:48

谢谢您的回答:在我的程序中插入我尝试过的那些消息,就像我添加的解释代码一样,显示了elisp没有elisp问题,但是我在设计上有些地方错了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13913551

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档