Related
I'm in love with Ruby. In this language all core functions are actually methods. That's why I prefer postfix notation – when the data, which I want to process is placed left from the body of anonymous processing function, for example: array.map{...}. I believe, that it has advantages in how easy is this code to read.
But Mathetica, being functional (yeah, it can be procedural if you want) dictates a style, where Function name is placed left from the data. As we can see in its manuals, // is used only when it's some simple Function, without arguments, like list // MatrixForm. When Function needs a lot of arguments, people who wrote manuals, use syntax F[data].
It would be okay, but my problem is the case F[f,data], for example Do[function, {x, a, b}]. Most of Mathematica functions (if not all) have arguments in exactly this order – [function, data], not [data, function]. As I prefer to use pure functions to keep namespace clean instead of creating a lot of named functions in my notebook, the argument function can be too big – so big, that argument data would be placed on the 5-20th line of code after the line with Function call.
This is why sometimes, when evil Ruby nature takes me under control, I rewrite such functions in postfix way:
Because it's important for me, that pure function (potentially big code) is placed right from processing data. Yeah I do it and I'm happy. But there are two things:
this causes Mathematica's highlighting parser problem: the x in postfix notation is highlighted with blue color, not turquoise;
everytime when I look into Mathematica manuals, I see examples like this one: Do[x[[i]] = (v[[i]] - U[[i, i + 1 ;; n]].x[[i + 1 ;; n]])/ U[[i, i]], {i, n, 1, -1}];, which means... hell, they think it's easy to read/support/etc.?!
So these two things made me ask this question here: am I so bad boy, that use my Ruby-style, and should I write code like these guys do, or is it OK, and I don't have to worry, and should write as I like to?
The style you propose is frequently possible, but is inadvisable in the case of Do. The problem is that Do has the attribute HoldAll. This is important because the loop variable (x in the example) must remain unevaluated and be treated as a local variable. To see this, try evaluating these expressions:
x = 123;
Do[Print[x], {x, 1, 2}]
(* prints 1 and 2 *)
{x, 1, 2} // Do[Print[x], #]&
(* error: Do::itraw: Raw object 123 cannot be used as an iterator.
Do[Print[x], {123, 1, 2}]
*)
The error occurs because the pure function Do[Print[x], #]& lacks the HoldAll attribute, causing {x, 1, 2} to be evaluated. You could solve the problem by explicitly defining a pure function with the HoldAll attribute, thus:
{x, 1, 2} // Function[Null, Do[Print[x], #], HoldAll]
... but I suspect that the cure is worse than the disease :)
Thus, when one is using "binding" expressions like Do, Table, Module and so on, it is safest to conform with the herd.
I think you need to learn to use the styles that Mathematica most naturally supports. Certainly there is more than one way, and my code does not look like everyone else's. Nevertheless, if you continue to try to beat Mathematica syntax into your own preconceived style, based on a different language, I foresee nothing but continued frustration for you.
Whitespace is not evil, and you can easily add line breaks to separate long arguments:
Do[
x[[i]] = (v[[i]] - U[[i, i + 1 ;; n]].x[[i + 1 ;; n]]) / U[[i, i]]
, {i, n, 1, -1}
];
This said, I like to write using more prefix (f # x) and infix (x ~ f ~ y) notation that I usually see, and I find this valuable because it is easy to determine that such functions are receiving one and two arguments respectively. This is somewhat nonstandard, but I do not think it is kicking over the traces of Mathematica syntax. Rather, I see it as using the syntax to advantage. Sometimes this causes syntax highlighting to fail, but I can live with that:
f[x] ~Do~ {x, 2, 5}
When using anything besides the standard form of f[x, y, z] (with line breaks as needed), you must be more careful of evaluation order, and IMHO, readability can suffer. Consider this contrived example:
{x, y} // # + 1 & ## # &
I do not find this intuitive. Yes, for someone intimate with Mathematica's order of operations, it is readable, but I believe it does not improve clarity. I tend to reserve // postfix for named functions where reading is natural:
Do[f[x], {x, 10000}] //Timing //First
I'd say it is one of the biggest mistakes to try program in a language B in ways idiomatic for a language A, only because you happen to know the latter well and like it. There is nothing wrong in borrowing idioms, but you have to make sure to understand the second language well enough so that you know why other people use it the way they do.
In the particular case of your example, and generally, I want to draw attention to a few things others did not mention. First, Do is a scoping construct which uses dynamic scoping to localize its iterator symbols. Therefore, you have:
In[4]:=
x=1;
{x,1,5}//Do[f[x],#]&
During evaluation of In[4]:= Do::itraw: Raw object
1 cannot be used as an iterator. >>
Out[5]= Do[f[x],{1,1,5}]
What a surprise, isn't it. This won't happen when you use Do in a standard fashion.
Second, note that, while this fact is largely ignored, f[#]&[arg] is NOT always the same as f[arg]. Example:
ClearAll[f];
SetAttributes[f, HoldAll];
f[x_] := Print[Unevaluated[x]]
f[5^2]
5^2
f[#] &[5^2]
25
This does not affect your example, but your usage is close enough to those cases affected by this, since you manipulate the scopes.
Mathematica supports 4 ways of applying a function to its arguments:
standard function form: f[x]
prefix: f#x or g##{x,y}
postfix: x // f, and
infix: x~g~y which is equivalent to g[x,y].
What form you choose to use is up to you, and is often an aesthetic choice, more than anything else. Internally, f#x is interpreted as f[x]. Personally, I primarily use postfix, like you, because I view each function in the chain as a transformation, and it is easier to string multiple transformations together like that. That said, my code will be littered with both the standard form and prefix form mostly depending on whim, but I tend to use standard form more as it evokes a feeling of containment with regards to the functions parameters.
I took a little liberty with the prefix form, as I included the shorthand form of Apply (##) alongside Prefix (#). Of the built in commands, only the standard form, infix form, and Apply allow you easily pass more than one variable to your function without additional work. Apply (e.g. g ## {x,y}) works by replacing the Head of the expression ({x,y}) with the function, in effect evaluating the function with multiple variables (g##{x,y} == g[x,y]).
The method I use to pass multiple variables to my functions using the postfix form is via lists. This necessitates a little more work as I have to write
{x,y} // f[ #[[1]], #[[2]] ]&
to specify which element of the List corresponds to the appropriate parameter. I tend to do this, but you could combine this with Apply like
{x,y} // f ## #&
which involves less typing, but could be more difficult to interpret when you read it later.
Edit: I should point out that f and g above are just placeholders, they can, and often are, replaced with pure functions, e.g. #+1& # x is mostly equivalent to #+1&[x], see Leonid's answer.
To clarify, per Leonid's answer, the equivalence between f#expr and f[expr] is true if f does not posses an attribute that would prevent the expression, expr, from being evaluated before being passed to f. For instance, one of the Attributes of Do is HoldAll which allows it to act as a scoping construct which allows its parameters to be evaluated internally without undo outside influence. The point is expr will be evaluated prior to it being passed to f, so if you need it to remain unevaluated, extra care must be taken, like creating a pure function with a Hold style attribute.
You can certainly do it, as you evidently know. Personally, I would not worry about how the manuals write code, and just write it the way I find natural and memorable.
However, I have noticed that I usually fall into definite patterns. For instance, if I produce a list after some computation and incidentally plot it to make sure it's what I expected, I usually do
prodListAfterLongComputation[
args,
]//ListPlot[#,PlotRange->Full]&
If I have a list, say lst, and I am now focusing on producing a complicated plot, I'll do
ListPlot[
lst,
Option1->Setting1,
Option2->Setting2
]
So basically, anything that is incidental and perhaps not important to be readable (I don't need to be able to instantaneously parse the first ListPlot as it's not the point of that bit of code) ends up being postfix, to avoid disrupting the already-written complicated code it is applied to. Conversely, complicated code I tend to write in the way I find easiest to parse later, which, in my case, is something like
f[
g[
a,
b,
c
]
]
even though it takes more typing and, if one does not use the Workbench/Eclipse plugin, makes it more work to reorganize code.
So I suppose I'd answer your question with "do whatever is most convenient after taking into account the possible need for readability and the possible loss of convenience such as code highlighting, extra work to refactor code etc".
Of course all this applies if you're the only one working with some piece of code; if there are others, it is a different question alltogether.
But this is just an opinion. I doubt it's possible for anybody to offer more than this.
For one-argument functions (f#(arg)), ((arg)//f) and f[arg] are completely equivalent even in the sense of applying of attributes of f. In the case of multi-argument functions one may write f#Sequence[args] or Sequence[args]//f with the same effect:
In[1]:= SetAttributes[f,HoldAll];
In[2]:= arg1:=Print[];
In[3]:= f#arg1
Out[3]= f[arg1]
In[4]:= f#Sequence[arg1,arg1]
Out[4]= f[arg1,arg1]
So it seems that the solution for anyone who likes postfix notation is to use Sequence:
x=123;
Sequence[Print[x],{x,1,2}]//Do
(* prints 1 and 2 *)
Some difficulties can potentially appear with functions having attribute SequenceHold or HoldAllComplete:
In[18]:= Select[{#, ToExpression[#, InputForm, Attributes]} & /#
Names["System`*"],
MemberQ[#[[2]], SequenceHold | HoldAllComplete] &][[All, 1]]
Out[18]= {"AbsoluteTiming", "DebugTag", "EvaluationObject", \
"HoldComplete", "InterpretationBox", "MakeBoxes", "ParallelEvaluate", \
"ParallelSubmit", "Parenthesize", "PreemptProtect", "Rule", \
"RuleDelayed", "Set", "SetDelayed", "SystemException", "TagSet", \
"TagSetDelayed", "Timing", "Unevaluated", "UpSet", "UpSetDelayed"}
SaveDefinitions is a nice option of Manipulate. It causes Manipulate to store any definitions used for its creation inside the Manipulate panel. A Manipulate made this way can be copied to an empty notebook and will still work on its own. Additionally, your working notebook containing many such Manipulates also doesn't turn into a flurry of pink boxes with printed error messages below it upon opening. Great!
However, all this goodness has its dark side which can bite you real hard if you are not aware of it. I've had this in a notebook I had been working on for a few days, but I present you with a step-by-step toy example scenario which recreates the problem.
In this scenario you want to create a Manipulate showing a plot of a nice wavy function, so you define this (please make a window size like this, this is important):
The definition is nice, so we keep it for the next time and make it an initialization cell. Next we add the Manipulate, and execute it too.
f[x_] := x^2
Manipulate[
Plot[n f[x], {x, -3, 3}],
{n, 1, 4},
SaveDefinitions -> True
]
All works great, the Manipulate really shines, it is a good day.
Just being your paranoid self you check whether the definition is OK:
Yeah, everything still checks out. Fine. But now it occurs to you that a better wavy function would be a sine, so you change the definition, execute, and being paranoid, check:
Everything still fine. You're ready from a day's hard work you save your work and quit. [Quit kernel]
Next day. You start your work again. You evaluate the initialization cells in your notebook. Definition still good? Check.
Now, you scroll down to your Manipulate box (no need to re-execute thanks to the SaveDefinitions), play a little with the slider. And scroll back up.
Being the paranoid you, you once more check the definition of f:
Lo and behold, someone has changed the definition behind your back! And nothing executed between your first and second Information(?) check according to the In[] numbers (In[1]: def of f, In[2] first ?, In[3] second ?).
What happened? Well, it's the Manipulate of course. A FullForm reveals its internal structure:
Manipulate[Plot[n*f[x],{x, -3, 3}],{{n, 2.44}, 1, 4},Initialization:>{f[x_] := x^2}]
There you have the culprit. The initialization part of the box defines f again, but it's the old version because we didn't re-evaluate the Manipulate after modifying its definition. As soon as the manipulate box gets on the screen, it is evaluated and you've got your old definition back. Globally!
Of course, in this toy example it is immediately clear something strange is happening. In my case, I had a larger module in a larger notebook in which I, after some debugging, had changed a small part. It seemed to work, but the next day, the same bug that had bugged me before hit again. It took me a couple of hours before I realized that one of the several Manipulates that I used to study the problem at hand from all sides was doing this.
Clearly, I'm tempted to say, this is unwanted behavior. Now, for the obligatory question: what can we do to prevent this behind-your-back behavior of Manipulate from occurring other than re-executing every Manipulate in your notebook each time you change a definition that might be used by them?
Here is an attempt. The idea is to identify symbols with DownValues or some other ...Values inside your manipulated code, and automatically rename them using unique variables / symbols in place of them. The idea here can be executed rather elegantly with the help of cloning symbols functionality, which I find useful from time to time. The function clone below will clone a given symbol, producing a symbol with the same global definitions:
Clear[GlobalProperties];
GlobalProperties[] :=
{OwnValues, DownValues, SubValues, UpValues, NValues, FormatValues,
Options, DefaultValues, Attributes};
Clear[unique];
unique[sym_] :=
ToExpression[
ToString[Unique[sym]] <>
StringReplace[StringJoin[ToString /# Date[]], "." :> ""]];
Attributes[clone] = {HoldAll};
clone[s_Symbol, new_Symbol: Null] :=
With[{clone = If[new === Null, unique[Unevaluated[s]], ClearAll[new]; new],
sopts = Options[Unevaluated[s]]},
With[{setProp = (#[clone] = (#[s] /. HoldPattern[s] :> clone)) &},
Map[setProp, DeleteCases[GlobalProperties[], Options]];
If[sopts =!= {}, Options[clone] = (sopts /. HoldPattern[s] :> clone)];
HoldPattern[s] :> clone]]
There are several alternatives of how to implement the function itself. One is to introduce the function with another name, taking the same arguments as Manipulate, say myManipulate. I will use another one: softly overload Manipulate via UpValues of some custom wrapper, that I will introduce. I will call it CloneSymbols. Here is the code:
ClearAll[CloneSymbols];
CloneSymbols /:
Manipulate[args___,CloneSymbols[sd:(SaveDefinitions->True)],after:OptionsPattern[]]:=
Unevaluated[Manipulate[args, sd, after]] /.
Cases[
Hold[args],
s_Symbol /; Flatten[{DownValues[s], SubValues[s], UpValues[s]}] =!= {} :>
clone[s],
Infinity, Heads -> True];
Here is an example of use:
f[x_] := Sin[x];
g[x_] := x^2;
Note that to use the new functionality, one has to wrap the SaveDefinitions->True option in CloneSymbols wrapper:
Manipulate[Plot[ f[n g[x]], {x, -3, 3}], {n, 1, 4},
CloneSymbols[SaveDefinitions -> True]]
This will not affect the definitions of original symbols in the code inside Manipulate, since it were their clones whose definitions have been saved and used in initialization now. We can look at the FullForm for this Manipulate to confirm that:
Manipulate[Plot[f$37782011751740542578125[Times[n,g$37792011751740542587890[x]]],
List[x,-3,3]],List[List[n,1.9849999999999999`],1,4],RuleDelayed[Initialization,
List[SetDelayed[f$37782011751740542578125[Pattern[x,Blank[]]],Sin[x]],
SetDelayed[g$37792011751740542587890[Pattern[x,Blank[]]],Power[x,2]]]]]
In particular, you can change the definitions of functions to say
f[x_]:=Cos[x];
g[x_]:=x;
Then move the slider of the Manipulate produced above, and then check the function definitions
?f
Global`f
f[x_]:=Cos[x]
?g
Global`g
g[x_]:=x
This Manipulate is reasonably independent of anything and can be copied and pasted safely. What happens here is the following: we first find all symbols with non-trivial DownValues, SubValues or UpValues (one can probably add OwnValues as well), and use Cases and clone to create their clones on the fly. We then replace lexically all the cloned symbols with their clones inside Manipulate, and then let Manipulate save the definitions for the clones. In this way, we make a "snapshot" of the functions involved, but do not affect the original functions in any way.
The uniqueness of the clones (symbols) has been addressed with the unique function. Note however, that while the Manipulate-s obtained in this way do not threaten the original function definitions, they will generally still depend on them, so one can not consider them totally independent of anything. One would have to walk down the dependency tree and clone all symbols there, and then reconstruct their inter-dependencies, to construct a fully standalone "snapshot" in Manipulate. This is doable but more complicated.
EDIT
Per request of #Sjoerd, I add code for a case when we do want our Manipulate-s to update to the function's changes, but do not want them to actively interfere and change any global definitions. I suggest a variant of a "pointer" technique: we will again replace function names with new symbols, but, rather than cloning those new symbols after our functions, we will use the Manipulate's Initialization option to simply make those symbols "pointers" to our functions, for example like Initialization:>{new1:=f,new2:=g}. Clearly, re-evaluation of such initialization code can not harm the definitions of f or g, and at the same time our Manipulate-s will become responsive to changes in those definitions.
The first thought is that we could just simply replace function names by new symbols and let Manipulate initialization automatically do the rest. Unfortunately, in that process, it walks the dependency tree, and therefore, the definitions for our functions would also be included - which is what we try to avoid. So, instead, we will explicitly construct the Initialize option. Here is the code:
ClearAll[SavePointers];
SavePointers /:
Manipulate[args___,SavePointers[sd :(SaveDefinitions->True)],
after:OptionsPattern[]] :=
Module[{init},
With[{ptrrules =
Cases[Hold[args],
s_Symbol /; Flatten[{DownValues[s], SubValues[s], UpValues[s]}] =!= {} :>
With[{pointer = unique[Unevaluated[s]]},
pointer := s;
HoldPattern[s] :> pointer],
Infinity, Heads -> True]},
Hold[ptrrules] /.
(Verbatim[HoldPattern][lhs_] :> rhs_ ) :> (rhs := lhs) /.
Hold[defs_] :>
ReleaseHold[
Hold[Manipulate[args, Initialization :> init, after]] /.
ptrrules /. init :> defs]]]
With the same definitions as before:
ClearAll[f, g];
f[x_] := Sin[x];
g[x_] := x^2;
Here is a FullForm of produced Manipulate:
In[454]:=
FullForm[Manipulate[Plot[f[n g[x]],{x,-3,3}],{n,1,4},
SavePointers[SaveDefinitions->True]]]
Out[454]//FullForm=
Manipulate[Plot[f$3653201175165770507872[Times[n,g$3654201175165770608016[x]]],
List[x,-3,3]],List[n,1,4],RuleDelayed[Initialization,
List[SetDelayed[f$3653201175165770507872,f],SetDelayed[g$3654201175165770608016,g]]]]
The newly generated symbols serve as "pointers" to our functions. The Manipulate-s constructed with this approach, will be responsive for updates in our functions, and at the same time harmless for the main functions' definitions. The price to pay is that they are not self-contained and will not display correctly if the main functions are undefined. So, one can use either CloneSymbols wrapper or SavePointers, depending on what is needed.
The answer is to use initialization cell as initialization for the Manipulate:
Manipulate[
Plot[n f[x], {x, -3, 3}], {n, 1, 4},
Initialization :> FrontEndTokenExecute["EvaluateInitialization"]]
You can also use DynamicModule:
DynamicModule[{f},
f[x_] := x^2;
Manipulate[Plot[n f[x], {x, -3, 3}], {n, 1, 4}]]
You do not need SaveDefinitions -> True in this case.
EDIT
In response to Sjoerd's comment. With the following simple technique you do not need to copy the definition everywhere and update all copies if you change the definition (but you still need to re-evaluate your code to get updated Manipulate):
DynamicModule[{f}, f[x_] := x^2;
list = Manipulate[Plot[n^# f[x], {x, -3, 3}], {n, 2, 4}] & /# Range[3]];
list // Row
What is the symbol $ used for internally?
I do not mean the compound forms x$388 or $5 etc., just the $ by itself.
I am wondering if this is a valid object to use in notation, or what I will break if I do.
It is unwise to have user variables that end in an odd number of $ characters (not counting the first character). x$, y$$$, and $$ are all poor choices for variable names.
This is because appending an odd number of $ to an identifier is a technique called "lexical renaming," which the Mathematica kernel uses to avoid conflicts in variable names when higher-order functions return functions that use the same variable names as their parents. This technique is used in a variety of scoping constructs, including Function, Module, With, and Rule; here is an example with Function:
In[1]:= f = Function[{x, y}, Function[{x}, x+y]]
Out[1]= Function[{x, y}, Function[{x}, x + y]]
In[2]:= f[2,3]
Out[2]= Function[{x$}, x$ + 3]
In[3]:= ?*`x$
Global`x$
Attributes[x$] = {Temporary}
In short, appending $ characters is a system-internal renaming mechanism, and identifiers of this form are recognized by Mathematica as "lexically renamed" versions of the $-less forms, with Temporary attribute. It is not recommended to use variables of this form in your own code.
Mathematica is a term-rewriting language that can behave like a lexically scoped functional language by use of internal rewriting mechanisms such as "lexical renaming."
In version 7, symbol System`$
used to be already created in a fresh kernel, but not used for anything as far as I know. In version 8, symbol $ is not pre-created:
In[1]:= Context["$"]
During evaluation of In[1]:= Context::notfound: Symbol $ not found. >>
Out[1]= Context["$"]
I would agree with Szabolcs that code using $ in System context might break in future versions, as well as any other code that modifies System symbols.
As I learned recently there are some types of expressions in Mathematica which are automatically parsed by the FrontEnd.
For example if we evaluate HoldComplete[Rotate[Style[expr, Red], 0.5]] we see that the FrontEnd does not display the original expression:
Is it possible to control such behavior of the FrontEnd?
And is it possible to get complete list of expressions those are parsed by the FrontEnd automatically?
EDIT
We can see calls to MakeBoxes when using Print:
On[MakeBoxes]; Print[HoldComplete#Rotate["text", Pi/2]]
But copy-pasting the printed output gives changed expression: HoldComplete[Rotate["text", 1.5707963267948966]]. It shows that Print does not respect HoldComplete.
When creating output Cell there should be calls for MakeBoxes too. Is there a way to see them?
I have found a post by John Fultz with pretty clear explanation of how graphics functionality works:
In version 6, the kernel has
absolutely no involvement whatsoever
in generating the rendered image.
The steps taken in displaying a
graphic in version 6 are very much
like those used in displaying
non-graphical output. It works as
follows:
1) The expression is evaluated, and
ultimately produces something with
head Graphics[] or Graphics3D[].
2) The resulting expression is passed
through MakeBoxes. MakeBoxes has a
set of rules which turns the graphics
expression into the box language which
the front end uses to represent
graphics. E.g.,
In[9]:= MakeBoxes[Graphics[{Point[{0, 0}]}], StandardForm]
Out[9]= GraphicsBox[{PointBox[{0, 0}]}]
Internally, we call this the "typeset"
expression. It may be a little weird
thinking of graphics as being
"typeset", but it's fundamentally the
same operation which happens for
typesetting (which has worked this way
for 11 years), so I'll use the term.
3) The resulting typeset expression is
sent via MathLink to the front end.
4) The front end parses the typeset
expression and creates internal
objects which generally have a
one-to-one correspondence to the
typeset expression.
5) The front end renders the internal
objects.
This means that the conversion is performed in the Kernel by a call to MakeBoxes.
This call can be intercepted through high-level code:
list = {};
MakeBoxes[expr_, form_] /; (AppendTo[list, HoldComplete[expr]];
True) := Null;
HoldComplete[Rotate[Style[expr, Red], 0.5]]
ClearAll[MakeBoxes];
list
Here is what we get as output:
One can see that MakeBoxes does not respect HoldAllComplete attribute.
The list of symbols which are auto-converted before sending to the FrontEnd one can get from FormatValues:
In[1]:= list =
Select[Names["*"],
ToExpression[#, InputForm,
Function[symbol, Length[FormatValues#symbol] > 0, HoldAll]] &];
list // Length
During evaluation of In[1]:= General::readp: Symbol I is read-protected. >>
Out[2]= 162
There are two aspects to what you witness. First, transcription of the expression you entered into boxes and rendering those boxes by Front-End. By default the output is typeset using StandardForm, which has a typesetting rule to render graphics and geometric transforms. If you use InputForm, there are no such rule. You can control which form is used via Preferences->Evaluation.
You can convince yourself that HoldComplete correctly did its job by using InputForm or FullForm on the input, or using InputForm display on the output cell.
EDIT Using the OutputForm:
In[13]:= OutputForm[%]
Out[13]//OutputForm= HoldComplete[Rotate[expr, 0.5]]
In regard to your question about complete list of symbols, it includes Graphics, geometric operations, and possibly others, but I do not know of the complete list.
Not quite an answer, but in Preferences > Evaluation there are options to "Only use textual boxes when converting (input|output) to typeset forms."
If you check these, then using Cell > Convert To... > StandardForm etc... will show the Rotate[..] instead of the visually rotated result.
John Fultz has recently answered my question on converting TableForm to "typeset" expressions and it is worth to cite it here since it amplifies (while partially contradicts) the general explanation cited in my previous answer:
ToBoxes is returning precisely what
the kernel sends to the front end
without variation (except, in the
general case, for the evaluation
semantics and side effects possibly
being different, but that's not an
issue in your example).
The issue is that the front end has
two different specifications for
specifying GridBox options... one of
which dates back to version 3, and the
other, more expansive set dates to
version 6. The front end understands
both sets of options, but
canonicalizes anything it receives to
the version 6 options.
GridBox is the only box which has had
such a wholesale change of options,
and it was necessary to support new
functionality we added in v6. But the
front end will continue to understand
the old options for a seriously long
time (probably forever), as the old
options show up not only in certain
kernel typesetting constructs, but in
legacy notebook files.
ToBoxes[] of TableForm is creating the
legacy options, as there's been no
need to update the typesetting of
TableForm in a while (ToBoxes[] of
Grid, on teh other hand, uses modern
options). The conversion is done by
the front end. You could rely on the
front end to do the conversion for
you, or you could figure out how the
options map yourself.
So in this case the final stage of the conversion of the expression is done by the FrontEnd.
I would like to automatically determine whether given object is Combinatorica or Mathematica 8.0 Graph.
It doesn't seem that FullForm has enough information to tell which one is which
(* output of Combinatorica`CompleteGraph[1] *)
Graph[List[],List[List[List[0,0]]]]
(* output of System`CompleteGraph[1] *)
Graph[List[1],List[]]
Mathematica, however, is able to tell them apart and renders one as a text string and another as visual object. Is there
Way to view "hidden" information in expressions that doesn't show in FullForm
Way to look at the rules Mathematica uses to render expressions?
Update:
It seems that Head gives different result for two graphs even though displayed heads are identical. Defining function as f[a_System'Graph] and f[a_Combinatorica'Graph] results in correct version being called
Head returns different values for the two types of graphs:
In[1]:= g1 = Combinatorica`CompleteGraph[1];
In[2]:= g2 = System`CompleteGraph[1];
In[3]:= Combinatorica`Graph === Head[#] & /# {g1, g2}
Out[3]= {True, False}
In[4]:= System`Graph === Head[#] & /# {g1, g2}
Out[4]= {False, True}
As for question 1, you have limited options for viewing the "hidden" information in non-symbolic objects like graphs, images, etc. You can call built-in Mathematica functions that have access to the native object representation. There are functions specific to the object types (like VertextCount or ImageDimensions) or more generic (like CurrentValue or PropertyValue). You are at the mercy of the MMA documentation to find comprehensive listings of such functions. Alternatively, you can sometimes glean useful information by inspecting the cell expression of an output cell containing such an object. But that can be hit or miss.
As for question 2, WRI typically protects the rendering rules for built-in functionality. Also, some functionality (like the drawing tools and graph editors) appears to be built directly into the notebook interface itself. You might get lucky inspecting the up-values or down-values on rendering functions such as MakeBoxes and Format, etc. Again, it is a bit hit or miss.