ketxu 发表于 2022-7-6 08:56:41

[Help] Limit of recursive

Hi all ^^
I've tried to use recursive with a huge list, and find out that it has limit, but i don't know what exactly number ?
See in this Ex with LM:mAssoc :

(defun LM:mAssoc ( key lst / pair )   (if (setq pair (assoc key lst))       (cons (cdr pair) (LM:mAssoc key (cdr (member pair lst))))   ))(defun test (num / lst)(setq i 0)(repeat num (setq lst (cons(cons 1 (setq i (1+ i))) lst))))
Then test :
Please help me. Thank all ^^

irneb 发表于 2022-7-6 09:05:38

Not sure ... but it seems the largest value in your code which doesn't produce the error is 19996.
 
You could of course use an iterative MAssoc:
;; Multiple assoc, by Lee Mac(defun MAssoc (key lst / pair return) (while (setq pair (assoc key lst))   (setq return (cons (cdr pair) return)         lst    (cdr (member pair lst))   ) ) (reverse return))Eg.:
Command: (length (Massoc 1 (test 1000000)))1000000Strangely I have another recursive MAlloc function:
(defun mAssocR1 (key lst / res) (if (and lst (setq res (assoc key lst)))   (cons (cdr res) (mAssocR1 key (cdr (member res lst)))) ))This gets a single value more before the error happens:
Command: (length (mAssocR1 1 (test 19997)))19997Command: (length (mAssocR1 1 (test 19998)))Hard error occurred ***internal stack limit reached (simulated)So I guess for large lists you'd be better off going with iterative routines. To check which you'd prefer, look at this thread: http://www.cadtutor.net/forum/showthread.php?55931-mAssoc-implementations

David Bethel 发表于 2022-7-6 09:18:08

Recursion limits used to be dependent on your hardware.Maybe it still is.   -David

Lee Mac 发表于 2022-7-6 09:26:40

Recursion is always limited by the size of the stack memory it is allocated. When you run a program a 'stack' of activation records are maintained, there is one activation record for every active method - a method is 'active' if it has been called but hasn't yet returned, e.g.:
 

(defun _copycat ( x )   (if (atom x)       x       (cons (_copycat (car x)) (_copycat (cdr x)))   ))Here, the 'cons' method is still active when the recursive call is made. The activation record stores the parameters/variables and 'return address' for the method. The return address tells the interpreter where in the code to continue evaluation after the method returns.
 
When you call a method, such as 'cons' above, the activation record is 'pushed' onto the stack memory. When the method returns, the return address is read and the activation record is 'popped' from the stack memory.
 
However, now consider the case of recursion: the activation record for the 'cons' method remains on the stack when the recursive call is made; similarly, another activation record is pushed onto the stack when the next recursive call is made, and another, and another, until the recursion reaches the base case and the method returns - at which point the activation records are 'popped' from the stack at each level of the recursion.
 
Therefore the limiting factor is the size of the allocated stack memory, limiting how many activation records can be pushed onto the stack, and hence how many levels of recursion can be achieved.

ketxu 发表于 2022-7-6 09:30:36

^^ Thanks all. From now on, i will try to avoid it. App can be slow, but can't crash ^^

Lee Mac 发表于 2022-7-6 09:36:10

 
On the contrary, recursion is usually far slower than iterative solutions.
 
Exaggerated example:
 

(defun fib_recurse ( n )   (if (

ketxu 发表于 2022-7-6 09:45:34

So... what is the reason to use recursion somewhere if it Short, but slow and dificult to understand ? ^^

Lee Mac 发表于 2022-7-6 09:56:39

 
In some cases it results in concise and elegant solutions, and for others it is almost the obvious choice, such as when processing nested lists.

ketxu 发表于 2022-7-6 10:00:45

Oh, right.. Thank you Lee. You help me like a "live dictionary" ^^
页: [1]
查看完整版本: [Help] Limit of recursive