Understanding function evaluation ...

(Apparently I had problems finding a proper title for this post!)

Dear All,

I was playing around with the simple idea of switching evaluation of some functions globally off or on. Please have a look at the following minimal example:

ClearAll[func, validQ, foo]

(* defining some function - with "evaluation switch": *)
func[arg_?validQ] := arg

(* switching evaluation OFF: *)
validQ[_] = False;

(* making a simple setting: *)
foo = func[a];

(* result - as expected: *)
{foo, func[a]}
(* Out:  {func[a],func[a]}  *)

(* switching evaluation ON: *)
validQ[_] = True;

(* `foo` does not evaluate! *)
{foo, func[a]}
(* Out:  {func[a], a}  *)

So my question is: Why on Earth I cannot make foo evaluate. Obviously I am missing here some very basic point …

Regards and many thanks – Henrik

Interesting question for which I have no answer unfortunately, but I hope to find out by leaving a message here…

Henrik,

The problem is because of Set[] (=) vs SetDelayed[] (:=)

When you defined foo with =, validQ was false. If you define foo with := it will use the value of validQ at evaluation time, not at define time.

I hope this helps,

Neil

I tried that, changing all to SetDelayed, but also didn’t work for me…

Oops, I guess I should have tried it first!

In[1]:= func[arg_ /; validQ] := arg
foo[a_] := func[a]

In[3]:= validQ = False;
        foo[p]
Out[4]= func[p]
    
In[5]:= validQ = True;
        foo[p]
Out[6]= p

Dear Sander, Neil, Hans,

many thanks for looking into that problem! Using SetDelayed was my first guess too. @Hans Milton: Yes, I had found that out already, thank you, and this is probably the way to go. But I basically would like to understand, why my approach above is not working …

Best regards – Henrik
[at0]: https://community.wolfram.com/web/hansmilton

That is exactly the use case for Update although the documentation about it won’t give you in depth insights.

Shortly, once evaluated expressions are internally marked as such and won’t undergo reevaluation for efficiency purposes. Unless something triggers them, like Update.

validQ[_] = True;    
Update[func];

{foo, func[a]}
{a, a}

Hello Kuba, very interesting, perfect explanation, many thanks!

Best regards – Henrik