[solved]
I have something similar with these four functions: base, init, func and some. The func is recursive and calls itself: in the "stop case" it would call some and return its value, then it should return control back to "init", wherefrom it is invoked; the latter being once called from base.
base
-> init
-> func
-> init
-> func
-> some
|
_________+
|
v
; should continue from here (in `func`)
[not anymore]
Instead, after the first call to some, the control is yielded directly to base, skipping what I would expect to be the intermediate (init,func) pair call(s).
I actually tried several simpler cases using block, return and recursion (e.g., "mutual tail-recursive factorial"), and all worked well. I mention that func uses a test helper function that catch a throw (but I tried even an example with (catch 'test (throw 'test 0)), and it was ok); just so whatever could my real program have something causing the issue.
This is elisp: each defun commences with block, and all functions use return, as in the following.
[I switched from using "defun/block" to "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)
The pack variable is my value-list as data structure. I also use func to reiterate itself (in tail-recursive call) with a special accumulating-parameter so that I avoid "imperative" while.
So instead of what I would expect (each > is paired by <)
base->
init->
func->
init->
func->
some->
<-some
<-func
<-init
func-> ; tail-recursion
<+func
<1func
<-init
<-base
my program behaves as follows.
base
-> init
-> func
-> init
-> func
-> some
|
__________________________+
|
v
; control yielded here (to `base`)
[not anymore]
Why is the control yielded too soon back to the start of the program, and not continue in the first call to func, after return from the second call via init?
Appreciate any help,
Sebastian
somenow.block/returntechnique? (i.e., the functionstring-match...?). I have the code in a public repository, but to the end purpose i'm at only 20%, and it has to do with parsingLaTeXcode lines).