1
$\begingroup$

I'm still thinking about how to implement Condition with anonymous patterns. And now I think I've found a way to implement it, but again, a suspected unclear documentation blocked me......

It's said in documentation that:

HoldPattern[expr] is equivalent to expr for pattern matching, but maintains expr in an unevaluated form.


But in this example, I simply adds a HoldPattern to the original okay pattern, then it generates a message and stop evaluation:

{{},{a,a},{a,b},{a,a,a}}/.{(Pattern[Evaluate[x=Unique[]],_]/;(Echo@x; True))..}->xxx

A seires of $--an integer-- is returned

{{},{a,a},{a,b},{a,a,a}}/.{HoldPattern[(Pattern[Evaluate[x=Unique[]],_]/;(Echo@x; True))]..}->xxx

Pattern: First element in pattern Pattern[Evaluate[x=Unique[]],_] is not a valid pattern name.


It seems that HoldPattern didn't really hold the pattern all the time, or else it won't say those Pattern stuff is invalid because when actually evaluating, the x=Unique[] will evaluate first then everything will be fine.

Is this yet another unclear explanation in documentation or it's my mis-implementation of HoldPattern?

And are there anyway I can solve this problem?

Thanks!


Some further explanation

I found out that though we cannot easily use anonymous pattern with Condition directly, we can create some single use symbol using Unique[] and then use them as names used in Condition. This will be identical as anonymous Condition, right~ But one crucial thing is to let Unique[] run again and again in multiple matches instead of calculating only once and leave there.

HoldPattern is designed for this job as it will surpress calculation in the first place and rerun each time pattern matcher want to check a match. But it seems that HoldPattern did something when nothing should be done, probably something like pre-processing, which result in this situation.

$\endgroup$
1
  • $\begingroup$ Can you explain why you need to avoid naming the pattern inside Condition? $\endgroup$
    – Szabolcs
    Commented Aug 17, 2016 at 11:11

2 Answers 2

5
$\begingroup$

HoldPattern has the attribute HoldAll. Because of this Evaluate[x=Unique[]] never evaluates to a symbol. Notice that Evaluate is not at the first level within HoldPattern, thus it will have no effect.

Note the difference:

Hold[Evaluate[1+1]]
(* Hold[2] *)

Hold[ f[Evaluate[1+1]] ]
(* Hold[f[Evaluate[1 + 1]]] *)

Evaluate has an effect only at the first level within a function with Hold* attribute.

$\endgroup$
7
  • $\begingroup$ so are there any solution to this? I mean, "design something similar to HoldPattern but holds only when inputting, in other words, having a HoldFirst attribute." $\endgroup$
    – Wjx
    Commented Aug 17, 2016 at 11:34
  • $\begingroup$ @Wjx define "inputting". $\endgroup$
    – Kuba
    Commented Aug 17, 2016 at 11:36
  • $\begingroup$ I mean to store the content of HoldPattern in its original way using HoldAll attribute. keep the whole thing free from pre-processing. then when using it in pattern matching tests, release all the holds and run just like a normal expression. just like what a function with HoldAll attribute usually do. $\endgroup$
    – Wjx
    Commented Aug 17, 2016 at 11:59
  • $\begingroup$ So, make it simpler, how to let Evaluate run wherever it is? $\endgroup$
    – Wjx
    Commented Aug 18, 2016 at 0:29
  • $\begingroup$ @Wjx That is not possible due to how the evaluator works. The evaluator simply doesn't look beyond level 1 inside of an expression with the HoldAll attribute. What you could do, in general (not necessarily here), is to use Replace/ReplaceAll to replace Evaluate[...] with its evaluated version, wherever it is in a held expression. $\endgroup$
    – Szabolcs
    Commented Aug 18, 2016 at 9:02
2
$\begingroup$

Ahh, I think I know what's happening here. I think it is that the documentation is a bit ambiguous:

HoldPattern actually will hold the whole pattern all the time and only recognize all pattern matching parts like _, __ or ___. So for example, I use HoldPattern[Plus[_,_]] it will hold everything even in pattern matching process. So actually HoldPattern is not eqivelent to normal patterns even when matching.

So in my case, HoldPattern even hold the naming part in Pattern[Evaluate[x=Unique[]],_] and in pattern matching, it will try to find something like Evaluate[x=Unique[]]_ but without evaluation. of couse only symbol is accepted in the first part of Pattern, so though in evaluations, Evaluate[x=Unique[]] returns a symbol, in HoldPattern, it will just stay in HoldForm and keep as an Expression, which leads to the error message.

So my question now is how to design something similar to HoldPattern but holds only when inputting, in other words, having a HoldFirst attribute.

$\endgroup$
3
  • 1
    $\begingroup$ That's probably subjective but I see your point. Maybe you could reduce your question so that it becomes a more generic/readable for future readers? $\endgroup$
    – Kuba
    Commented Aug 17, 2016 at 11:21
  • $\begingroup$ The only way I can think of getting around this problem is to inject the evaluated expression using With. $\endgroup$
    – QuantumDot
    Commented Aug 28, 2016 at 9:48
  • $\begingroup$ @QuantumDot great idea! Why not post an answer? I would like to offer an bounty if you really succeeded! :) $\endgroup$
    – Wjx
    Commented Aug 28, 2016 at 9:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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