Skip to content

Conversation

@bdlucas1
Copy link
Collaborator

Following on to the recent discussion, I thought it would be worthwhile to add a Module test to lambdify_compile.

# evaluation in lambdify_compile is able to expand them to a
# non-procedural expression
#
dict(name="Module[{sum=0, i}, For[i=1, i<=3, i++, sum += Sin[i #]]; sum]&", args=[1]),
Copy link
Contributor

@mmatera mmatera Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, this case works. But what about

Module[{sum=0, i}, For[i=1, i<=#, i++,  sum += Sin[i #]]; sum]&

?
This shuld be something equivalent to Sum[Sin[i*x],{i,1,x}], however, if it is evaluated before giving a value to x, the result is 0.. This expression tricks lambdify_compile. Ideally, when an expression like this is passed to Plot or to Compile, a wrapper function should be returned, that carries the regular evaluation of the expression, when the argument takes a numerical value.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, thanks. I think I see where I went wrong. Because an If expression like this is left unevaluated if n does not have a value and therefore the conditional can't be evaluated:

In[1]:= If[0<n,3,4]
Out[1]= If[0 < n, 3, 4]

I thought the same would apply to the Module - the whole thing would remain unevaluated because the conditional in the For couldn't be evaluated, and therefore the Module would remain after evaluation and the compilation would fail, rather than giving the wrong answer. But now I see that isn't the case, for example (swapping out If for For for simplicity):

(* n is not bound so If can't be evaluated, but still Module presses on *)
In[2]:= Module[{sum=0},If[0<n,sum:=17, sum:=18];sum]
Out[2]= 0

(* everything can now be evaluated, side effects are different, result is different *)
In[3]:= Module[{sum=0},If[0<1,sum:=17, sum:=18];sum]
Out[3]= 17

(* verifying that the If is not evaluated *)
In[6]:= Module[{sum=0},If[0<n,sum:=17, sum:=18]]
Out[6]= If[0 < n, sum$3 := 17, sum$3 := 18]

In other words, even though the If inside the Module remains unevaluated, that doesn't stop Module from
evaluating everything else in the Module that it can, local side effects and all, ignoring the fact that those local side effects might be different if everything could be evaluated.

So given that this test case relies on accidentally correct behavior, I'll withdraw it. Handling compilation of Module correctly doesn't seem high priority to me from the perspective of my main concern, plotting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants