How do I stop recursion happening in a Format/Interpretation Mathematica construction? - wolfram-mathematica

This question follows on from the answer given by Michael Pilat in Preventing “Plus” from rearranging things. There he defined a custom + notation using
Format[myPlus[expr__]] := Row[Riffle[{expr}, "+"]]
The problem with this is you can't copy and paste the output (although % or Out[] still works). To get around this you should use the Interpretation type facility which allows an expression to be displayed as one thing, but interpreted as another when supplied as input. My modification of Michael's answer is
Format[myPlus[expr__]] := Interpretation[Row[{expr}, "+"], myPlus[expr]]
This can be copied and pasted successfully. The problem lies in modifying copied expressions. You can convert a copied expression back to InputForm using Ctrl-Shift-I then change anything you want and use the InputForm in any expression. But if you try to change it back to StandardForm using Ctrl-Shift-N then you enter an recursion where the second argument in the Interpretation repeatedly gets evaluated. This is despite Interpretation having the attribute HoldAll (which works properly during normal evaluation).
Normally, when defining simple notations I use the low-level MakeBoxes, eg
myPlus/:MakeBoxes[myPlus[expr__],fmt_]:=With[{r=Riffle[MakeBoxes/#{expr},"+"]},
InterpretationBox[RowBox[r],myPlus[expr]]]
which works perfectly, so I have not encountered this recursion problem before.
So my question (finally) is:
What went wrong with my Format type command and how can it by fixed?
Or: How do you make a high-level equivalent of my MakeBoxes type command?

I consulted with a colleague about this, and his recommendation was essentially that putting up-value definitions on MakeBoxes as you demonstrate is better than using Format when you want things to be tightly integrated from output back to input. Format isn't really intended to produce output that can be re-used as input, but just to format output, hence the unexpected recursion with Interpretation when converting to StandardForm, etc.
You might find the function ToBoxes a useful complement to MakeBoxes.
Finally, here's a tutorial about box structures.
HTH!

Related

Why do I get Mathematica Hold error for this simple code?

Please look into attached files. Why do I get Hold error in the first one but not in the second? The problem seems to be in the names of variables used. Thanks.
The short answer is that subscripts in Mathematica behave in unexpected ways and should be avoided. You are inviting headache just for the sake of making code look pretty.
When you do this:
F:=Subscript[F,j]
and then evaluate F you probably are thinking the un-subscripted F is an independent symbol, but what happens is the F inside Subscript[] on the r.h.s gets evaluated with the delayed definition of F and so you have an infinite recursion trying to build:
Subscript[Subscript[Subscript[....,j],j],j]
As you see in your second example if you use a different symbol on the left it works fine.
It also works fine if you dispense with the pretty formatting and do:
F:=Fj
as now Fj is a plain symbol unrelated to F

Why do Julia programmers need to prefix macros with the at-sign?

Whenever I see a Julia macro in use like #assert or #time I'm always wondering about the need to distinguish a macro syntactically with the # prefix. What should I be thinking of when using # for a macro? For me it adds noise and distraction to an otherwise very nice language (syntactically speaking).
I mean, for me '#' has a meaning of reference, i.e. a location like a domain or address. In the location sense # does not have a meaning for macros other than that it is a different compilation step.
The # should be seen as a warning sign which indicates that the normal rules of the language might not apply. E.g., a function call
f(x)
will never modify the value of the variable x in the calling context, but a macro invocation
#mymacro x
(or #mymacro f(x) for that matter) very well might.
Another reason is that macros in Julia are not based on textual substitution as in C, but substitution in the abstract syntax tree (which is much more powerful and avoids the unexpected consequences that textual substitution macros are notorious for).
Macros have special syntax in Julia, and since they are expanded after parse time, the parser also needs an unambiguous way to recognise them
(without knowing which macros have been defined in the current scope).
ASCII characters are a precious resource in the design of most programming languages, Julia very much included. I would guess that the choice of # mostly comes down to the fact that it was not needed for something more important, and that it stands out pretty well.
Symbols always need to be interpreted within the context they are used. Having multiple meanings for symbols, across contexts, is not new and will probably never go away. For example, no one should expect #include in a C program to go viral on Twitter.
Julia's Documentation entry Hold up: why macros? explains pretty well some of the things you might keep in mind while writing and/or using macros.
Here are a few snippets:
Macros are necessary because they execute when code is parsed,
therefore, macros allow the programmer to generate and include
fragments of customized code before the full program is run.
...
It is important to emphasize that macros receive their arguments as
expressions, literals, or symbols.
So, if a macro is called with an expression, it gets the whole expression, not just the result.
...
In place of the written syntax, the macro call is expanded at parse
time to its returned result.
It actually fits quite nicely with the semantics of the # symbol on its own.
If we look up the Wikipedia entry for 'At symbol' we find that it is often used as a replacement for the preposition 'at' (yes it even reads 'at'). And the preposition 'at' is used to express a spatial or temporal relation.
Because of that we can use the #-symbol as an abbreviation for the preposition at to refer to a spatial relation, i.e. a location like #tony's bar, #france, etc., to some memory location #0x50FA2C (e.g. for pointers/addresses), to the receiver of a message (#user0851 which twitter and other forums use, etc.) but as well for a temporal relation, i.e. #05:00 am, #midnight, #compile_time or #parse_time.
And since macros are processed at parse time (here you have it) and this is totally distinct from the other code that is evaluated at run time (yes there are many different phases in between but that's not the point here).
In addition to explicitly direct the attention to the programmer that the following code fragment is processed at parse time! as oppossed to run time, we use #.
For me this explanation fits nicely in the language.
thanks#all ;)

Fortran, Meaning of Unary* operator in function calls?

I am attempting to make modifications to an old fortran code to get it to handle a slightly different binary input file format. In the process of doing this I have been encountering * used in a unary fashion. For example, this code found within a loop:
CALL EVENT1(QDRBUF(IPNTR+EVTHSZ),EVTSIZ,EVTID,
- *11000,*10000,*80000)
There are other cases as well but as far as I have seen / remember it is only in function calls. What is this doing?
I'm not a Fortran guy, but this question intrigued me, so I did some looking. It appears to be an alternate return specifier. The number after the asterisk is a label that can be used in place of a normal return, almost like catching an exception.

mathematica does not show the SubsuperscriptBox correctly in the plot label

folks, I met a weird problem while using mathematica. As you can see from the attached screenshot, the typesetting is somehow interpreted as plain text.
Is there a way to fix this?
Thanks very much! (I am so confused. It actually shows the correct thing sometimes...)
One can observe that this problem extends beyond the scope of PlotLabel. It also affects superscripts and subscripts. One way to avoid the problem is to insert a space between the sub/superscript object, and the adjacent symbol.
I tried to post an example, but the error is low level enough that it is impossible to paste the expression in its original form. I will have to resort to merely including a picture of what I see. Although the two lines appear similar, there is a space between "e2" and "(T)" in the second one.
In Mathematica 7.0.1:
This is somewhat similar to Known issues with copying code from Mathematica to other platforms? in that both bugs deal with "2D" objects inside of a FractionBox.
I can reproduce this with V7.0.1, but not with V8.0.1.
The simplest workaround I've found is to structure the fraction using separate strings for the numerator and denominator.
You could also take a typesetting approach to things instead of using strings at all:
Format[\[Epsilon][x_, sub_, sup_], TraditionalForm] :=
Subsuperscript[\[Epsilon], sub, sup][x]
Graphics[{}, PlotLabel -> Style[Gamma[T]/\[Epsilon][T, 0, 2]]]
Unlike Brett, I was unable to reproduce the bug in either version 7 or 8.
However, if you're using mathematics in the PlotLabel, it is probably better to let Mathematica render it using its own typesetting. The trick is HoldForm
For example:
Plot[x, {x, 0, 1},
PlotLabel -> HoldForm[\[Eta][T]/Subsuperscript[\[Epsilon], 0,2][T]]]
will produce
irrespective of any definitions for Eta or Epsilon.
As pointed out by Brett, this actually doesn't work in version 7.0.1, since it appears that there is a bug in TraditionalForm, that puts square brackets in the construction
Power[f,i][x]//TraditionalForm.
The work around for this is to use Superscript instead of Power:
Similarly for the denominator in the above plot, instead of using
Power[Subscript[...]][T], use Subsuperscript[...][T]:
This means that you can not use the standard (keyboard shortcuts or palette for) 2D input, because the SubsuperscriptBox that is produced using this is interpreted as Power[Subscript[...]]. I've fixed the code for the graphics above to reflect this.
Note that this TraditionalForm bug has been fixed in Mathematica version 8.

Is there a way to check if a label is already defined in LaTeX?

I edited the question after David Hanak's answer (thanks btw!). He helped with the syntax, but it appears that I wasn't using the right function to begin with.
Basically what I want is to let the compiler ignore multiple definitions of a certain label and just use the first. In order to do that, I thought I'd just do something like this:
\makeatletter
\newcommand{\mylabel}[1]{
\#ifundefined{#1}{\label{#1}}{X}
}
\makeatother
This does not work though, because the first option is always chosen (it doesn't matter if the label is defined or not). I think the \#ifundefined (and the suggested \ifundefined) only work for commands and not for labels, but I don't really know much about LaTeX. Any help with this would be great! Thanks!
Much later update:
I marked David Hanak's response as the correct answer to my question, but it isn't a complete solution, although it really helped me.
The problem is, I think but I'm no specialist, that even though David's code checks to see if a label is defined, it only works when the label was defined in a previous run (i.e. is in the .aux file). If two \mylabels with the same name are defined in the same run, the second will still be defined. Also, even if you manage to work around this, it will make LaTeX use the first label that you defined chronologically, and not necessarily the first in the text.
Anyway, below is my quick and dirty solution. It uses the fact that counters do seem to be defined right away.
\newcommand{\mylabel}[1]{%
\#ifundefined{c##1}{%
\newcounter{#1}%
\setcounter{#1}{0}%
}{}%
\ifthenelse{\value{#1} > 0}{}{%
\label{#1}%
\addtocounter{#1}{1}%
}%
}
I'm not sure if it is necessary to initialize the counter to 0, as it seems like a likely default, but I couldn't find if that was the case, so I'm just being safe.
Also, this uses the 'ifthen' package, which I'm not sure is necessary.
I am also not a LaTeX expert, however after one day of trying and searching the internet the following worked for me. I have used a dummy counter to solve the problem. Hopefully this helps, apparently not many people are looking for this.
\newcommand{\mylabel}[1]{
\ifcsname c##1\endcsname%
\else%
\newcounter{#1}\label{#1}%
\fi%
}
# is a special character in LaTeX. To make your declaration syntactically correct, you'll have to add two more lines:
\makeatletter
\newcommand{\mylabel}[1]{
\#ifundefined{#1}{\label{#1}}{X}
}
\makeatother
The first line turns # into a normal letter, the last line reverses its effect.
Update: You might also want to take a look at the "plain" \ifundefined LaTeX macro.
Update 2
Okay, I did some research to figure out the answer to the real problem. The thing is that defining a label does not create a macro by that name; it prepends a "r#" to it. So try the following:
\makeatletter
\newcommand{\mylabel}[1]{
\#ifundefined{r##1}{\label{#1}}{X}
}
\makeatother
For more technical details, refer to line 3863 of latex.ltx in your LaTeX distribution (where it says \def\newlabel{\#newl#bel r}).
By Victor Eijkhout, "TeX by Topic", p.143:
\def\ifUnDefinedCs#1{\expandafter\ifx\csname#1\endcsname\relax}
This can be used to check whether a label is defined; if not, the label is printed:
\newcommand{\myautoref}[1]{\ifUnDefinedCs{r##1}{\color{magenta}\IDontKnow\{#1\}}\else\autoref{#1}\fi}

Resources