3
$\begingroup$

I'd need to apply all functions in a list to a BlankNullSequence (___)

But when I tried

Through[{Abs, Dot, Plus, Power, Times}[___]]
(*{Abs[___], ___, ___, ___, ___}*)

it works well only with Abs. I'd like to have the result

{Abs[___], Dot[___], Plus[___], Power[___], Times[___]}

How can I have this as an output? Why in my example there is a difference among Abs, Dot, Plus etc.?

$\endgroup$
6
  • $\begingroup$ Through[{Abs, Defer[Dot], Defer[Plus], Defer[Power], Defer[Times]}[___]]? $\endgroup$
    – kglr
    Commented Apr 1, 2017 at 18:49
  • 2
    $\begingroup$ Onlly Abs holds its argument if it's non-numeric. That's your issue here. The Defer kglr proposes will work. An alternative is to use (HoldPattern[#[__]]&)/@<funcs> because you probably want that for pattern matching anyway. $\endgroup$
    – b3m2a1
    Commented Apr 1, 2017 at 18:51
  • 1
    $\begingroup$ Defer is only for formatting within notebooks. Unless the output is copied and pasted back, the head Defer will stay in the expression. $\endgroup$
    – Szabolcs
    Commented Apr 1, 2017 at 18:52
  • $\begingroup$ @Giancarlo, this is unrelated to BlankNullSequence. Plus[x] will evaluate to x for any x. It can't be kept as Plus[x] unless it wrapped with Hold or similar. What are you actually trying to do? Perhaps you want HoldPattern. $\endgroup$
    – Szabolcs
    Commented Apr 1, 2017 at 18:54
  • $\begingroup$ @Szabolcs this question is related to this I want to calculate ComplexExpand[Conjugate[ff[x]], {ff[x]}] and I have to specify that the functions inside ff are complex; for example: ComplexExpand[Conjugate[Abs[x]+Dot[x, y]], {x, y,Dot[___],Abs[___],Plus[___]}]. My idea is to search the functions (Symbol) that are inside ff, append to them the [___] and put the list in ComplexExpand $\endgroup$
    – Giancarlo
    Commented Apr 1, 2017 at 19:32

1 Answer 1

10
$\begingroup$

It is important to understand that functions will attempt to operate on pattern objects (like ___) as they will any other, and sometimes this confounds the intent you had for them (the pattern objects).

Consider for example:

Plus[_, _, _]
3 _

This evaluates to 3 _ (FullForm Times[3, Blank[]]), which is not a pattern expression that will match x + y + z, because _ is not treated specially in evaluation, so it is just like Plus[x, x, x] evaluating to 3 x.

Now consider:

Abs[x]
Dot[x]
Plus[x]
Power[x]
Times[x]
Abs[x]

x

x

x

x

What to do about this will depend on why you are preparing these patterns.

If you want to use all patterns at once I would suggest Alternatives:

pat = (Abs | Dot | Plus | Power | Times)[___]

(* unchanged by evaluation *)

Now e.g.

MatchQ[a^b, pat]
True

If you really need individual pattern expressions you will need to prevent evaluation from making undesired changes. The canonical method for that is HoldPattern as proposed by MB1965 in a comment:

HoldPattern[#[___]] & /@ {Abs, Dot, Plus, Power, Times}
{HoldPattern[Abs[___]],
 HoldPattern[Dot[___]],
 HoldPattern[+___], 
 HoldPattern[Power[___]],
 HoldPattern[Times[___]]}

Note: +___ is due to an output formatting rule and not evaluation itself, and the pattern will still match a + b etc. See Returning an unevaluated expression with values substituted in for more on this.


Recommended reading:

Possible duplicate:

$\endgroup$
1
  • $\begingroup$ nice explanation $\endgroup$
    – Ali Hashmi
    Commented Apr 1, 2017 at 20:49

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.