3

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.?

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
Giancarlo
  • 712
  • 4
  • 11
  • Through[{Abs, Defer[Dot], Defer[Plus], Defer[Power], Defer[Times]}[___]]? – kglr Apr 01 '17 at 18:49
  • 2
    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. – b3m2a1 Apr 01 '17 at 18:51
  • 1
    Defer is only for formatting within notebooks. Unless the output is copied and pasted back, the head Defer will stay in the expression. – Szabolcs Apr 01 '17 at 18:52
  • @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. – Szabolcs Apr 01 '17 at 18:54
  • @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 – Giancarlo Apr 01 '17 at 19:32
  • @Giancarlo Try ComplexExpand[Conjugate[Abs[x] + Dot[x, y]], {x, y, _Dot, _Plus}]. – Alexey Popkov Apr 02 '17 at 14:24

1 Answers1

10

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:

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371