2

[解决了]

我有与这四个函数类似的东西:baseinit和。是递归的并调用自身:在“停止情况”中,它将调用并返回其值,然后将控制返回给“ ”,从中调用它;后者曾经被调用 from 。funcsomefuncsomeinitbase

base
  -> init
       -> func
            -> init
                 -> func
                      -> some
                    |
           _________+
          |
          v
          ; should continue from here (in `func`)

[不再]

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

block实际上,我使用,return和递归(例如,“相互尾递归”)尝试了几个更简单的情况factorial,并且都运行良好。我提到它func使用了一个辅助test函数(但我什至尝试了一个带有 的示例,并且没关系);就这样,我的真实程序可能会导致问题。catchthrow(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`)

[不再]

为什么控制权过早地回到程序的开头,而不是在第一次调用时继续funcreturn从第二次调用 via开始init

感谢任何帮助,

塞巴斯蒂安

4

2 回答 2

1

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

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

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

(block nil
 ...

 (return (func ...)))

return“取消”了该块,并且与根本没有该块具有相同的效果,除非在 " " 中调用的某些函数...确实有 areturn 而没有a block。所以return这里取消了可能的返回点func

于 2012-12-17T20:40:00.977 回答
0

感谢您的回答:将我尝试的那些消息插入到我的程序中,就像我为解释添加的代码一样,结果表明 没有defun*问题elisp,但是我在设计中犯了一些错误。

于 2012-12-20T13:58:48.100 回答