# is there a way to construct a pattern that would trigger when an expression is used as a held/unevaluated in some form?

For example, consider the following code

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


We use it, then f evaluates:

f[x]
(* 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

-

$Pre = Function[{x}, If[Count[Hold[x], HoldPattern[f[_]], ∞] =!= 0, Print["test"]]; x, HoldAll]  Functions like $Pre, $Post etc give nice effects but use them wisely. - 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... – zorank Mar 12 '14 at 18:33 @zorank Not sure if what you need but you can use Block to play with $Pre only there. – Kuba Mar 12 '14 at 18:48
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. – zorank Mar 13 '14 at 11:58 @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? – Kuba Mar 13 '14 at 12:05 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. – zorank Mar 13 '14 at 12:18