Jump to content

Recommended Posts

Posted (edited)

Hi guys,

 

I have a lisp routine (a very complex one with about 1500 lines or so), and for some reason, when I run a very deep recursion function, I ended up with something like an LPPTYPE which I've never heard of:

 

image.png.7cf6c0bdddb8b09b1d592e0ffa831577.png

 

On inspecting, I got:

 

image.thumb.png.067151611f6ba1e6326e020eec3ff17b.png

 

I think a better way of putting it is: it doesn't return an error, but the function returns inconsistent results that would otherwise work if the function doesn't malfunction from too many recursions (I guess that's what I can deduce from my failures)

 

The thing is, if the recursion isn't very deep, this won't show up and my code works as how it should work.

 

My recursive function (by logic) is something along the lines of:

 

(defun test (arg_list arg_string / continue)
    (if (setq continue (vl-remove-if-not some_condition arg_list))
	(apply 'append
	       (mapcar
		   '(lambda (x / result nextlist nextstring)
			;; some codes using x which eventually leads to (for example):
			(setq result '("desired1" "desired2" ;|...|; ) ; another list
			      nextlist '( "item1" "item2" ;|and so on|; )
			      nextstring "something2"
			      )
			(cons result (test nextlist nextstring))
			)
		   continue
		   )
	       )
	)
    )

 

Except rather than the code that short, it's about 150 lines or so.

 

If worse comes to worst, I'll probably do an iterative approach, though I'm not sure how this kind of recursive logic can be achieved using iteration approach. I really need help because I've been on this for days and still can't find an answer.

 

Thanks

Jonathan Handojo

Edited by Jonathan Handojo
Posted

When programming, always look for iterative ways firstly... Iteration is faster, more stable and better approach of solving things... Always avoid recursions as much as possible - that is meant even for small sub functions like (unique) or something similar... Every function that is iterative-recursive can be written the other way - recursive-iterative... You just have to think the way if it's recursive the way it won't call itself, but like repeating loops in (while, foreach) functions... Either ways (recursive or iterative) you have to define condition to exit loops - recursions (this is the key for solving translation of one way to other)... Things that are in body of sub are essentially the same and shouldn't change... Just keep in mind that BricsCAD has limit of list length that can be processed of 10,000,000 elements and AutoCAD 20,000,000 , but AutoCAD won't crash it will go in never ending calculations mode which is IMHO bad thing - if it's not possible to do something with data then crash is very important - you may be sitting for days thinking that it's working and instead it's doing nothing just spending el. energy... With recursions both CADs will and should crash with error reporting - stack limit reached or 'Heat in [gc] reached, but recursive way of coding is wrong approach IMO...

M.R.

Good luck...

Posted

Welcome to the "recursive" curse. :lol:

  • Funny 1
Posted (edited)

So now I just learned... it's called "recursive" for a reason eh? Nice pun

 

@hanhphuc the stack probably went too deep. I mean, after all, there were DCL dialogs involved in it too, and a very lengthy one at that as well. I did say it was about 150 lines or so, but it was calling a dialog function that was a further 700 or so (including all the action_tile and everything).

 

I did trace it slowly, using the watch window and printing after every 'curse'. Calling it at about 50 times is enough to spoil it and cause the error above (and it's not even consistent either, sometimes it returns something like an infinite nested list that when I run LM:flatten, my AutoCAD crashes). If there were only a few recursions, the function would return the desired result.

 

I'm trying to describe as best as I can, but I do not want to publish my codes or drawings here as you can say it's part of intellectual property.

Edited by Jonathan Handojo
Posted

Just break it down into chunks, or/and work it out bit by bit. - I don't think you'll get any better advise than that.

Personally I would take out the problematic subfoo itself and investigate it upon the different supplied arguments.

 

The description of your program reminds me of the last tough one I did (check the demo) -

A table via DCL, where each cell is a labeled button, some of them are used to take inputs, the others are recalculating the table after every dialog reappearance.

In the end a button that places a table in ACAD - which is actually an attributed block.

The DCL thing is like 600-row recursive function (TipTable2) that takes only 1 argument: mL - a matrix list, and returns a re-processed matrix list aswell,

and the return will be a valid argument for recalling it again - so I've got control over everything it does.

 

Your case of "too deep recursion combilend with DCL" doesn't make much sense to me - if the recursion is big it should be obviously used for lisp data processing,

and not for GUI interacting.

For instance your program should be either

unable to process recursively the giant nested list you have or 

unable to display the recursively processed list via DCL.

To get some precise help one should post the actual arguments, the actual sub (with its real body) and write the expected behaviour/return.

 

Haven't been posting here for quite a while.. been busy(and still busy) with other stuff. 🙄

TipTable2.jpg

TIP_2_Demo.rar

Posted
1 hour ago, rlx said:

nice to hear your still living Grrr 🖖

Agreed! Good to see you're still around. 🍻🍻

Posted

Seriously weird though, mapcar was returning a random value after I watched every recursion... So on mapcar, I watched each result returned by the function (let's say in the case below, I put 'result in the watch). The function returned the desired result after I watched every item x in the list lst. But then when I stepped into the function by pressing F8 again to get the value returned by mapcar, it returned something else. So instead of:

(setq rtn (mapcar '(lambda (x) 'result) lst))

 

I used last resort:

(progn (mapcar '(lambda (x) (setq rtn (cons 'result rtn))) lst) (reverse rtn))

 

It's just ridiculous...

Posted

Can you explain what it is your doing not the code but rather the task. Someone may have something.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...