# How do Forms affect the interpretation of Expressions?

Below are three formats for representing an undirected edge between vertices a and b:

ClearAll[a, b]
a \[UndirectedEdge] b
FullForm[a \[UndirectedEdge] b]
InputForm[a \[UndirectedEdge] b]


Here's a screenshot of the output (to be clear about it's appearance):

Now let's look at some other Forms:

a \[UndirectedEdge] b
OutputForm[a \[UndirectedEdge] b]
StandardForm[a \[UndirectedEdge] b]


Part works on the FullForm and InputForm as expected:

FullForm[a \[UndirectedEdge] b][[1, 2]]
InputForm[a \[UndirectedEdge] b][[1, 2]]

(* out *)
b
b


But Part does not return consistent results for other cases:

a \[UndirectedEdge] b[[1, 2]]
(a \[UndirectedEdge] b)[[1, 2]]
OutputForm[a \[UndirectedEdge] b][[1, 2]]
StandardForm[a \[UndirectedEdge] b][[1, 2]]
TraditionalForm[a \[UndirectedEdge] b][[1, 2]]


Can anyone help explain why Part gives different results? In particular, why doesn't it respond to all of the cases as if they were the FullForm version?

Edit

In retrospect, I realize that I was both (a) miscounting levels and (b) oblivious to the role of Forms as wrappers of expressions. The second issue is touched on by this contribution by R.M

-

The error is exactly what Part says:

There is no such level in that expression, and to convince yourself, look at {a, b}[[1, 2]] :)

The reason you see it in the *Forms is because they're all wrappers that affect display. In other words, although you see it as an undirected edge, its actual head is *Form.

OutputForm[a \[UndirectedEdge] b] // FullForm
(* OutputForm[UndirectedEdge[a, b]] *)


The additional head now allows you to index [[1, 2]]. Going back to my earlier example:

f[{a, b}][[1, 2]]
(* b *)

-
My goodness, it seems so clear now. –  David Carraher Apr 17 '12 at 16:27
R.M what witchcraft did you use to get the Publicist badge? –  Mr.Wizard Apr 17 '12 at 23:20
@Mr.Wizard =) $\$ –  rm -rf Apr 17 '12 at 23:22
Seriously, do you have a web page I could visit? –  Mr.Wizard Apr 17 '12 at 23:24

Part always works on the internal of the expression (the one you get from FullForm). However, the expression you apply it to is not the same in all your cases.

For a \[UndirectedEdge] b[[1, 2]], Part is applied only to b, which obviouzsly has no part [[1,2]].

For (a \[UndirectedEdge] b)[[1, 2]] the expression it works on is just UndirectedEdge[a,b]. There is no element [[1,2]] for this (element [[1]] is a which does not have a part [[2]]).

On the other hand in the third expression you take the part of OutputForm[a \[UndirectedEdge] b] of which [[1]] is a \[UndirectedEdge] b, and part [[2]] of that is b. The same holds for the other cases.

The point is that when encountered in the middle of an expression, OutputForm etc. are just normal functions taking place in the evaluation. Only if they are the outermost applied function, they are stripped from the result and only used for output. You can see this as follows:

In[2]:= FullForm[x]

Out[2]//FullForm= x

In[3]:= %//FullForm

Out[3]//FullForm= x

In[4]:= {FullForm[x]}

Out[4]= {x}

In[5]:= %//FullForm

Out[5]//FullForm= List[FullForm[x]]


You see, in Out[3], the FullForm is gone from the expression, while in Out[5] it's still there.

-
Looks like I was counting the head as a level! A silly mistake. But in the process I learned that Forms add an extra level, a wrapper, around an expression. –  David Carraher Apr 17 '12 at 16:28
@DavidCarraher: The head is just the zeroth element, for example f[a,b][[0]]==Head[f[a,b]]==f` –  celtschk Apr 17 '12 at 16:31
That makes sense, and is embarrassingly familiar. I'm inclined to delete the question, for being too elementary, but there may be other folks out there who can learn from the exchange so I'll leave it. –  David Carraher Apr 17 '12 at 16:34
@David - I wouldn't delete - it is exactly the sort of thing that will trip up newer and intermediate users, so having an answer they can find on mathematica.SE is a good idea. –  Verbeia Apr 17 '12 at 22:43