4

I was wondering if it is possible to override the head of symbols/operators. As a motivating example if I run:

example

Then Ket will be returned. But lets say I want Bob to be returned instead of Ket. Is such a thing possible? To go a little bit further, I'd like:

bob
to return BobKet and

alice

to return AliceKet so that I could make a function that recognizes these heads like: function

Thanks!

Here are the corresponding lines of code

Head[Ket[\[Placeholder]]]

Head[Ket[Subscript[x, B]]]

Head[Ket[Subscript[x, A]]]

combineBobAndAlice[b_BobKet, a_AliceKet] := Ket[{ {Subscript[b[[1, 1]], B], Subscript[a[[1, 1]], A]} }]

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
John Smith
  • 491
  • 3
  • 9
  • Please post your code as text that we can copy and paste to duplicate your results. – bill s Jan 28 '14 at 05:29
  • Apply is usually used to change the head of an expression. – Mike Honeychurch Jan 28 '14 at 05:32
  • 1
    that is true. I do not think you can change head of an Atom. Try Clear[bob]; r=1; r[[0]]=bob you'll get an error. But r = Sin[x]; r[[0]]=bob works. Now Head[r] returns bob. I think playing games with Heads to do what is asked here is the wrong way to go about writing a program. – Nasser Jan 28 '14 at 05:37
  • Nasser, thanks for that idea, it has pointed me in the right direction I think. – John Smith Jan 28 '14 at 05:45

1 Answers1

7

I don't believe it is possible to implement your literal request. While you can make an UpSet definition for Head:

Unprotect[Ket];
Head[Ket[_]] ^:= Bob
Head[Ket[Subscript[x, B]]] ^:= BobKet
Head[Ket[Subscript[x, A]]] ^:= AliceKet

Head[Ket[Subscript[x, B]]]
BobKet

Since Head is not actually used by the pattern matcher this does not produce your desired behavior:

f[_BobKet] := "hit!"
f[Ket[Subscript[x, B]]]
f[Ket[Subscript[x, B]]]

(I don't actually have Ket in version 7, but I see no reason for this not to work unless Ket is atomic.)

However, I can see no need for this behavior. Instead you should simply use a pattern that matches what you want it to match. You can assign patterns to global Symbols to use them easily, if that is your concern:

bob = HoldPattern @ Ket[Subscript[x, B]];
alice = HoldPattern @ Ket[Subscript[x, A]];

f[x : bob, y : alice] := {"it worked!", x, y}

f[Ket[Subscript[x, B]], Ket[Subscript[x, A]]]
{"it worked!", Ket[Subscript[x, B]], Ket[Subscript[x, A]]}

You can even use named patterns within a pattern, e.g.:

bob = HoldPattern @ Ket[Subscript[u_, B]];
alice = HoldPattern @ Ket[Subscript[v_, A]];

f[x : bob, y : alice] := {u, v}

f[Ket[Subscript[foo, B]], Ket[Subscript[bar, A]]]
{foo, bar}

I hope this helps you implement what you need.

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