rtoy / maxima

A Clone of Maxima's repo
Other
0 stars 0 forks source link

trace cause extra evaluation of function arguments #3151

Open rtoy opened 2 months ago

rtoy commented 2 months ago

Imported from SourceForge on 2024-07-07 14:56:13 Created by iandall on 2013-06-18 11:21:38 Original: https://sourceforge.net/p/maxima/bugs/2595


build_info(version="5.29.1",timestamp="2012-12-13 16:17:55",host="x86_64-redhat-linux-gnu",lisp_name="SBCL",lisp_version="1.1.2-1.fc18")

Consider the following definitions:

xf('f, 'var, val) := ev(f, [var:: val]);
xg(x) := sin(x);

and

y: %pi/2$
timer(xf)$ xf(xg(y), y, %pi/6); timer_info(); untimer(xf)$
xf(xg(y), y, %pi/6);

The first evaluation of xf() produces 1 whereas the second evaluation produces 1/2.

The same thing if you use trace() .. untrace().

It seems at the very least undesirable for trace and timer to alter the behaviour of the expressions that are being traced or timed.

rtoy commented 2 months ago

Imported from SourceForge on 2024-07-07 14:56:14 Created by rswarbrick on 2013-06-21 12:33:33 Original: https://sourceforge.net/p/maxima/bugs/2595/#f3de


A simpler example:

:::text
(%i39) fun ('var) := var;
(%o39)                         fun('var) := var
(%i40) x: 1$

(%i41) fun(x);
(%o41)                                 x
(%i42) trace(fun)$

(%i43) fun(x);
1 Enter fun [1]
1 Exit  fun 1
(%o43)                                 1
(%i44) untrace(fun);
(%o44)                               [fun]
(%i45) fun(x);
(%o45)                                 x
rtoy commented 2 months ago

Imported from SourceForge on 2024-07-07 14:56:17 Created by rswarbrick on 2013-06-21 12:55:13 Original: https://sourceforge.net/p/maxima/bugs/2595/#793c


More information on what's going on: Function application is normally done by expanding a function noun into its lambda form (usually stored as MEXPR on the symbol) and then calling MLAMBDA. MLAMBDA has special code to deal with functions that are defined with quoted variables (like 'var in fun above).

When a function gets traced, what we do is remove the translation property and instead we call a trace handler which actually evaluates the function. Unfortunately, we call MEVALARGS on the arguments before we pass them through to the trace handler. (This is done in the 'subr case in MEVAL1 in mlisp.lisp)

One possible fix is that we change the trace handlers to set an 'SUBR-NOEVAL property, which MEVAL1 looks for and, unlike with SUBR, doesn't evaluate the arguments beforehand.

Comments from people more experienced in this sort of thing? MEVAL1 has already got a ridiculously huge COND statement. It would be nice to repurpose something that already exists... (MFEXPR*?)

rtoy commented 2 months ago

Imported from SourceForge on 2024-07-07 14:56:21 Created by rswarbrick on 2013-07-01 22:04:17 Original: https://sourceforge.net/p/maxima/bugs/2595/#5141


Plea for help/ideas sent to mailing list: http://permalink.gmane.org/gmane.comp.mathematics.maxima.general/42756