Why am I unable to see the FullForm of ^^ (the shorthand notation for BaseForm)?

FullForm[HoldComplete[16 ^^ 2]]
(* HoldComplete[2] *)

FullForm[ToExpression["HoldComplete[16 ^^ 2]"]]
(* HoldComplete[2] *)

Trace[HoldComplete[16 ^^ 2],TraceInternal->True]
(* {} *)

My only clue is from the Possible Issues section on HoldComplete:

HoldComplete affects only evaluation; input transformations are still applied:

Is there a way to see the FullForm?


No, AFAIK there is no way to see the FullForm and I think your conclusion is correct. The ^^ is not an operator, it is a form how you can input a number. Effectively, this behavior applies to all form of numerical input.

enter image description here

For instance this is unholdable too

(* HoldComplete[1600] *)

Advanced expanation

To give a more thorough explanation, we have to look at the way an input string is converted into a Mathematica expression. My explanation might not be correct in all details, because I have no insight into the internal implementation, but in general, this conversion happens in two steps:

  • Lexical scanning of the input string which divides it into tokens
  • parsing of the tokens with respect to the syntax of Mathematica and the precedence of the operators

To give an example, look at the input string "BaseForm[33,2]". When it is tokenized, we see that it is split into the logical parts: identifiers, operators, braces, ..

"BaseForm[33,2]" // fultzTokenize // InputForm

(* {"BaseForm", "[", "33", ",", "2", "]"} *)

You find the tokenize implementation in this post. Regarding to the syntax of Mathematica, the [ indicates, that it is function call where BaseForm is the head of the function and 33 and 2 are its arguments.

This is reflected in the final parsing tree Hold[BaseForm[33, 2]] // TreeForm

Mathematica graphics

Remember, that to end up as separate node in the parsing tree, the input needs to be split up into several tokens. Let's see what happens, when we tokenize (or lexical scan) the special input forms:

"16^^2" // fultzTokenize // InputForm

(* {"16^^2"} *)

This means, that expression like 16^^2 are not split up because here ^^ is not an operator. Those expressions are recognized directly as number. Btw, is exactly how I have implemented it in the Mathematica plugin for IDEA. There, such constructs are seen by the parser as number. And if you look at my lexical scanner spec in line 47-65 you see, that the regexp for recognizing all kinds of numbers in Mathematica is at least a bit complex.

Now, you might finally ask the question, when is this 16^^2 converted into its final form? To the best of my knowledge, this is done silently by the kernel. If we use a LinkSnooper to watch the traffic between Front-End and Mathematica Kernel, we see for the evaluation of Hold[16^^4]

FE ---> K: EnterExpressionPacket[MakeExpression[BoxData[RowBox[{"Hold", "[", "16^^4", "]"}]], StandardForm]]
FE <--- K: OutputNamePacket["Out[8]= "]
FE <--- K: ReturnExpressionPacket[BoxData[RowBox[{"Hold", "[", "4", "]"}], StandardForm]]

You see the 16^^2 is sent to the kernel, but back comes, ignoring the Hold, the evaluated number.

  • 1
    $\begingroup$ Very good explanation. Thank you. $\endgroup$ – Chip Hurst Jan 3 '14 at 19:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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