For example, consider the following code

f[x_] := (Print["evaluated f"]; workWith[x]);

We use it, then f evaluates:

(* evaluated f, workWith[x] *)

When we use f in the assignment, f does not evaluate:

f[x] = 1
(* 1 *)

Is it possible to construct a pattern that will detect cases when f[x] is used unevaluated like in the Set command? For example, one could do

f /: Set[f[x_], rhs___] := somework when f is not evaluated

but that would only work specifically for the Set command. Is there a way to make it more generic?, for example like this

HeldExpression[f[x_]] := somework when f is not evaluated

would be great but, of course, HeldExpression does not exist.

I realized that

f /: HoldPattern[_[___,f[x_],___]] := work with f when used

actually triggers even if f is used in the context of the Set command, but it does not discriminate between to be evaluated (y=f[x];) and not to be evaluated (f[x]=1;) scenarios.

Regards Zoran


I'm not sure what is your goal at the end but the following works quite well:

$Pre = Function[{x},
                If[Count[Hold[x], HoldPattern[f[_]], ∞] =!= 0, Print["test"]]; x,

enter image description here

Functions like $Pre, $Post etc give nice effects but use them wisely.

  • $\begingroup$ thanks! exactly on the right track, if not the solution! I wonder, imagine a scenario where Pre is redefined someplace else (it is global variable right?). I supose one could use Protect[Pre]. Is there another way, without using global variables like Pre? Just curious... $\endgroup$
    – zorank
    Mar 12 '14 at 18:33
  • $\begingroup$ @zorank Not sure if what you need but you can use Block to play with $Pre only there. $\endgroup$
    – Kuba
    Mar 12 '14 at 18:48
  • $\begingroup$ That would not work. I am developing a utility package that needs that functionality. The package has to be used with other packages, and then it would define $Pre for everyone else, and they might not like it. That is the reason why I would like to avoid use of global variables. Another issue, I worry about the speed. My feeling is that having a pattern like match would be much faster then digging through every expression every time to find occurences of OBJ@f. $\endgroup$
    – zorank
    Mar 13 '14 at 11:58
  • $\begingroup$ @zorank you can set levelspec for Count. This is pattern matching so I;m not sure what you are after. About scope, yes, that may be a problem. Maybe getting a package could set ``Global``` context to be restricted to particular notebook so it would not spread over? $\endgroup$
    – Kuba
    Mar 13 '14 at 12:05
  • $\begingroup$ Very kind of you to try to help. I wonder, if one sets levelspec for Count it might miss some occurences, right? I would like to have a localized pattern mathcing definition that the user will never really see. that's all. changing $Pre makes me very, very nervous. I will rather stick to the HoldPattern[_[___,f[_],___]] idea. That can be made very local. Though I am not sure how costly it is, i.e. this pattern is so generic that it might be tested a larger number of times. $\endgroup$
    – zorank
    Mar 13 '14 at 12:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.