Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Is there any way to completely remove the head of an expression function?

For example, how would I remove the head Cos from Cos[a] to give only a as an output.

share|improve this question
1  
First@Cos[a]? –  Pickett Jun 9 at 0:03
1  
Note that all expressions have heads and bodies. These two are not separable. For example, a has head Symbol. All you can do is to replace a head with something else or extract parts of an expression. –  Oleksandr R. Jun 9 at 0:50
    
@Oleksandr I agree and would think that the closest thing to a headless expression is one with Sequence as head. –  acl Jun 9 at 2:36
    
@acl Identity –  Mike Honeychurch Jun 9 at 4:18
    
@MikeHoneychurch I was thinking about things like Sequence @@@ List[List[a, b], List[a, c]]. But you're right, for examples like in your answer Identity does the job. –  acl Jun 9 at 12:04

4 Answers 4

up vote 7 down vote accepted

You can actually Delete the head of the expression, which is part 0:

Delete[#, 0] & /@ {Cos[a], Sin[b], Tan[c]}
{a, b, c}

One case of interest may be held expressions. If our expression is:

expr = HoldComplete[2 + 2];

And the head we wish to remove is Plus, we cannot use these:

Identity @@@ expr
Sequence @@@ expr
expr /. Plus -> Identity
expr /. Plus -> Sequence
Replace[expr, _[x__] :> x, 1]

All produce e.g.:

HoldComplete[Identity[2, 2]]  (* or Sequence *)

We can use Delete or FlattenAt:

Delete[expr, {1, 0}]
FlattenAt[expr, 1]
HoldComplete[2, 2]
HoldComplete[2, 2]

You could also use a pattern that includes the surrounding expression on the right-hand-side, as demonstrated here, e.g.:

expr /. h_[_[x__]] :> h[x]
HoldComplete[2, 2]

Notes

As the documentation for Delete reads:

Deleting the head of a whole expression makes the head be Sequence.

Delete[Cos[a], 0]
Sequence[a]

Since this resolves to a in normal evaluation this should usually not be an issue.

share|improve this answer
    
+1, I like my held expressions. About "when there is no surrounding expression", I like this remark. To see that this is really the behaviour of Delete, rather than some post-processing of the kernel, you can evaluate: SetAttributes[seqHHA, {SequenceHold, HoldAll}]; seqHHA@Evaluate@Delete[Cos[a], 0]. So I disagree with your latest edit. The "a whole expression" here is the entire first argument of Delete, rather than any "subexpression" of the expression in the first argument. –  Jacob Akkerboom Jun 9 at 9:46
    
@Jacob I'm not sure what your example is intended to illustrate, and I don't know why you disagree with what I said. In your case you Evaluate Delete[Cos[a], 0] before seqHHA sees it, so there is effectively no surrounding expression. What am I missing? –  Mr.Wizard Jun 9 at 9:51
    
@Jacob I just saw the addendum to your comment above, and I think I understand now, as well as I suppose what the documentation is saying. Nevertheless I don't think that (the documentation) is written very clearly. –  Mr.Wizard Jun 9 at 9:58
    
I agree that the documentation is not very clear. But such a mistake (of being vague) is easily made I guess :). I'm glad we looked at this, the behaviour of Delete w.r.t. generating Sequence has puzzled me before. –  Jacob Akkerboom Jun 9 at 10:02
1  
@Jacob Would not your example be better written like this?: Attributes[seqHHA] = {SequenceHold}; seqHHA[Delete[Cos[a], 0]] –  Mr.Wizard Jun 9 at 10:17

Sequence might be useful if your expressions come inside other expressions. For example:

num = 10;
lst = MapThread[
  #1@#2 &,
  {
   RandomChoice[{Cos, Sin, Exp, Tan, Cot, ArcTan, ArcTanh}, num],
   RandomChoice[{x, y, z}, num]
   }
  ]

(*

{ArcTan[x], ArcTan[x], ArcTan[x], Cot[x], Cot[z], Cot[x], ArcTan[z], 
 ArcTanh[y], ArcTanh[x], Cot[y]}

*)

(this is just a long-winded way of producing a list), then

Sequence @@ # & /@ lst

(*
{x, x, x, x, z, x, z, y, x, y}
*)

Roughly, Sequence dissolves and its children get promoted whenever it appears as something other than the topmost head, eg f[Sequence[g]] evaluates to f[g]. Thus,

expr = f @@ lst
Sequence @@ # & /@ expr

(*

f[ArcTan[x], ArcTan[x], ArcTan[x], Cot[x], Cot[z], Cot[x], ArcTan[z], 
 ArcTanh[y], ArcTanh[x], Cot[y]]

f[x, x, x, x, z, x, z, y, x, y]

*)
share|improve this answer
    
Thanks for your input. –  Algohi Jun 9 at 0:25
5  
Sequence @@ # & /@ lst can be written more compactly as Sequence @@@ lst –  Bob Hanlon Jun 9 at 3:54
    
Note that Sequence will not evaluate inside a head with HoldAllComplete or SequenceHold attributes. –  Mr.Wizard Jun 9 at 9:35
    
@BobHanlon Good point, thanks –  acl Jun 9 at 12:01

You remove a head by replacing it with Identity

Cos[a] /. Cos -> Identity

For doing this over lots of expressions:

list = {ArcTan[x], ArcTan[x], ArcTan[x], Cot[x], Cot[z], Cot[x], 
  ArcTan[z], ArcTanh[y], ArcTanh[x], Cot[y]};

list[[All, 0]] = Identity

or

Identity @@@ list

etc

share|improve this answer

Does this come close?

Cos[a] /. Cos[a] -> a

Or

Cos[a] /. _[a] -> a

Or

First@Cos[a]

Or

list = {Sin@a, Cos@b};
First /@ list

{a, b}

share|improve this answer
    
The second one is good because you can apply it to functions without need to retype the functions in Replace all. thanks eldo. –  Algohi Jun 9 at 0:11
    
@Algohi- see my update :) –  eldo Jun 9 at 0:17
3  
Your second example doesn't remove the head, it just matches _[a] with literally a then always returns a. For example Cos[b] isn't matched. I guess you meant /. _[a___] -> a, so that eg lekker[b, c] /. _[a___] -> a works. –  acl Jun 9 at 0:25
    
@acl - Thanks - Just inspected the 4 forms by applying Head and FullForm to them - everything seems to be right. –  eldo Jun 9 at 0:33
1  
Sorry, I did not mean that your examples don't work, but that if the argument is not a then it does not get matched, because the a on the right hand side of /. is not a pattern. eg Cos[b] /. _[a] -> a evaluates to Cos[b], ie, the a is matched literally. You probably meant Cos[b] /. _[a_] -> a or, more generally (allowing for multiple arguments) Cos[b] /. _[a___] -> a. –  acl Jun 9 at 0:40

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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