# I am missing a function like HoldPattern

Temporary message: I am planning to edit this question, making the examples less confusing and by moving the things that are confusing to a separate question

For any confusion about expressions that Mathematica does not seem to fully evaluate, see this question

Throughout this question x is assumed to have a value. Maybe evaluate

x=3;


I have had a lot of difficult moments with Mathematica where I wished I could just make evaluation stop. One basic example is where you have want to do the following

Evaluate[Symbol["x"]] = 7


But x already has a value. In this example we can do something with ToExpression["x",InputForm, Hold] or as Leonid has suggested, ToHeldExpression, but this is not really the point.

Despite a warnings by Leonid, I like using Unevaluated. A similar problem arises here, as I will try to show. We might have

g[_Symbol]:="yay"


Then we can simply do

g[Unevaluated[x]]


-> "yay"

and be satisfied. However, we must realize that we cannot do something like

g[Sequence[Unevaluated[x]]]


-> g[Unevaluated[x]]

or, the trickier example, using

var := Unevaluated[Unevaluated[x]]


where I encourage you to do

var//Definition


-> var := Unevaluated[x]

In the tricky example, we can try

g[var]


-> g[Unevaluated[x]]

So that it does not evaluate to "yay" as we would have desired.

Edit

It may not seem natural at all to have Mathematica end up with an expression like

g[Unevaluated[x]]

which if you evaluate it gives something else. In my mind I was bluffing for a moment that I might understand what is going on, but I guess really I don't.

Also note that we have

With[
{yyyy = g[var]}
,
Identity[yyyy]
]


-> g[Unevaluated[x]]

which is even stranger. If this is a bug, please let me know. I guess I should have taken Leonids advice about Unevaluated :(. The function I defined below still works though...

End of edit

To come to the point, I feel like there should be a function like HoldPattern2, or HoldPatternRHS that works as follows

g[HoldPattern2[x]]


-> "yay"

and

g[Sequence[HoldPattern2[x]]]


-> "yay"

and

MatchQ[HoldPattern2[x], _Symbol]


-> True

I hope the usefulness of this speaks for itself..

At some point I thought for a minute that HoldForm could be used for this (which I am a bit embarrassed about).

My questions are

1. This function really does not exist, right?
2. There is no easy way to make this function, right?

Just now I tried the following definitions

ClearAll[holdPattern2]
SetAttributes[holdPattern2, HoldAll];

holdPattern2 /: f_Symbol[y___, holdPattern2[x_], z___] :=
f[y, Unevaluated[x], z]


This seems kind of unstabile, but at least we have

g[holdPattern2[x]]


-> "yay"

and

MatchQ[holdPattern2[x], _Symbol]


-> "yay"

and

z = 4;
holdPattern2[z] = 3;
z


-> 3

Edit

we even have

holdPattern2[r]:=x;
r//Definition


-> r := x

Which is nice.

End of edit

I would like to think more about the flaws of this function myself, but I already spent more time asking this question than I planned. Maybe it is an interesting find (actually I am quite happy it works for all the examples :D). Feedback is welcome!

• I don't think I understand what behavior you expect from this hold function. Should it evaluate to Unevaluated inside any function that is not a pattern test or construct? Also, this seems related to these: (17553), (24558), (24559) and possibly my step function. Commented May 14, 2013 at 1:03
• @Mr.Wizard Thank you for the link. I think especially your step function is useful here. holdPattern2 should not evaluate to Unevaluated. In the example where g[var] evaluates to g[Unevaluated[x]] I try to show that even though we end up with something that looks like what we want, this really does not work nicely as Unevaluated was not present at the moment rules associated with g were looked up. I was not expecting Mathematica to stop at g[Unevaluated[x]], which seems like a bug to me, but I guess it goes to show that this is just really bad practise...(cont) Commented May 14, 2013 at 10:07
• What I really want is a function that is invisible to some functions, in kind of the same way that HoldPattern is. holdPattern2 really does not do everything I want. In g[Sequence[holdPattern2[x]]] the rule for holdPattern2 gets used too soon. But consider this: hhhh := Evaluate[ToExpression["x", InputForm, holdPattern2]]. Then hhhh//Definition -> hhhh := x . Does that not look useful? :) Commented May 14, 2013 at 10:16
• I guess I can be satisfied with the possibility of writing g[holdPattern2@@Hold[x]] or things like that. We can always make something with head holdPattern2 on the inside of our function. So to clarify this really simulates the use of Unevaluated, but in cases where it was not originally present. Commented May 14, 2013 at 10:30