tony@oha.UUCP (Tony Olekshy) (12/23/90)
Question for xlisp internals gurus follows below... I just spent way too long debugging: (mapcar '(lambda (son) (send son :rpt-output menu$width)) (reverse menu$sons)) The problem is, of course, that the single quote should either be left off, or replaced with #'. I have taken the later course with all things that should be functions, as is done in xlstat. The reason this took so long to debug is that the quoted form was mostly working (!), but on long enough data sets there would arise cases where other instances of local variables named son were being garbage collected, and cases where xlisp would simply core dump. Since I've just been through the experience of adding c functions to xlisp, I was uncertain as to whether or not this was being caused by improperly protected temporary lvals in my code. Furthermore, I could only reproduce the problem with large data sets, and they take time to run. Oh well. Now my question for xlisp internals gurus is: is there some trivial code that would either: 1) promote a quoted lambda expression, as the first expression to mapcar, to a function (since it works on short data sets, perhaps the code to do such promotion is just missing the protection of the temporary lvals), or 2) produce an error message when mapcar's first argument is not a valid form? -- Yours etc., Tony Olekshy. Internet: tony%oha@CS.UAlberta.CA BITNET: tony%oha.uucp@UALTAMTS.BITNET uucp: alberta!oha!tony Blowing is not playing the flute, you must make use of your fingers.--Goethe
This is JaMira speaking ) (12/27/90)
In article <467@oha.UUCP> tony@oha.UUCP (Tony Olekshy) writes: >>I just spent way too long debugging: >> >> (mapcar '(lambda (son) (send son :rpt-output menu$width)) >> (reverse menu$sons)) I had a same problem, and *** xleval.c.orig Fri Jul 20 16:53:25 1990 --- xleval.c Fri Jul 20 16:54:24 1990 *************** *** 155,160 **** --- 155,163 ---- LVAL *oldargv,fun,val; int oldargc; + /* protect some pointers */ + xlsave1(fun); + /* get the function */ fun = xlfp[1]; *************** *** 204,209 **** --- 207,215 ---- /* remove the call frame */ xlsp = xlfp; xlfp = xlfp - (int)getfixnum(*xlfp); + + /* restore the stack */ + xlpop(); /* return the function value */ return (val); this works well so far. I hope this works for your case, too. -- Yosh Nishinaka (nisinaka@sra.co.jp) "One for all. All for one. Three for Five."
toma@sail.LABS.TEK.COM (Tom Almy) (12/28/90)
In article <NISINAKA.90Dec27030519@sraco1.us.sra.co.jp> nisinaka@sraco1.us.sra.co.jp ( Hello!! This is JaMira speaking ) writes: >In article <467@oha.UUCP> tony@oha.UUCP (Tony Olekshy) writes: > >>I just spent way too long debugging: > >> (mapcar '(lambda (son) (send son :rpt-output menu$width)) > >> (reverse menu$sons)) > I had a same problem, and [fix involving protecting pointer fun in xlapply deleted] >this works well so far. > I hope this works for your case, too. Yes it will work, but it doesn't truly address the problem and wastes a position in the stack. Normally fun would not need to be protected, since its value is the same as that in the argument stack (which also gets garbage collected). The problem comes when fun is a CONS (as in the original posting), and gets reassigned. Sometime ago, a fix was posted by Paul vanNiekerk that addresses the problem by storing the new function back into the argument stack. To fix, in xlapply() find the line "fun = xlclose(..." and replace with "xlfp[1] = fun = xlclose(...". Copies of xlisp distributed by me have this patch applied. As to the original poster's comment about the functional arguments (lambda ...) '(lambda ...) #'(lambda ...) seemingly performing the same way. The don't, and its not an error. The documentation states that the function argument given to eval can be a closure (first and third case) or a cons where the car is LAMBDA. In the second case, the closure will be built within the mapcar (in this case) function, and thus will have different free variable bindings than in the first or third case. The first and third case are identical in operation. Note that if a defined function was used instead of the lambda expression, then only #'fun will work since the other forms will use the value binding of fun. -- Tom Almy toma@sail.labs.tek.com <<< Note new address Standard Disclaimers Apply