I want a built-in function renamed without loss of any properties, I want the shorter name to appear in all results and to be recognized as input. Is it possible?
-
$\begingroup$ what do you mean by results? do you mean in the help notebooks, for instance? $\endgroup$– aclCommented Dec 19, 2012 at 23:39
-
$\begingroup$ @acl in the results, of course. I do not bother about help. Particularly I want to rename a function to another name which is already occupied by another built-in function. $\endgroup$– AnixxCommented Dec 19, 2012 at 23:42
-
1$\begingroup$ What function are you thinking of, for example? $\endgroup$– ZviovichCommented Dec 19, 2012 at 23:44
-
$\begingroup$ Related: mathematica.stackexchange.com/q/117/121 ; mathematica.stackexchange.com/q/4281/121 also Exposing Symbols to $ContextPath $\endgroup$– Mr.WizardCommented Dec 19, 2012 at 23:47
-
2$\begingroup$ @PatoCriollo I want Zeta to always refer to HurwitzZeta, both in results and in input. $\endgroup$– AnixxCommented Dec 20, 2012 at 0:43
4 Answers
I'm not sure I understand your request, but you can usually get what you want with some combination of $PreRead
and either Format
or MakeBoxes
definitions.
From my answers to other qeustions here are an example of $PreRead
behavior and control of output using Format
.
A direct replacement in input and output is possible with:
MakeBoxes[HurwitzZeta[x__], fmt_] := MakeBoxes[Zeta[x], fmt]
$PreRead = # /. {"Zeta" -> "HurwitzZeta"} &;
Then:
Zeta[3, -1/2] === HurwitzZeta[3, -1/2]
True
Sum[(n + a)^(-3/2), {n, 0, Infinity}]
Zeta[3/2, a] (* normally prints HurwitzZeta[3/2, a] *)
I'm not sure how you plan to avoid confusing HurwitzZeta
and Zeta
.
For example, the output of:
RSolve[f[a + 1] == f[a] - 1/Sqrt[a], f[a], a]
is normally:
{{f[a] -> C[1] + HurwitzZeta[1/2, a] - Zeta[1/2]}}
but with the rules above it prints:
{{f[a] -> C[1] + Zeta[1/2, a] - Zeta[1/2]}}
This does not seem correct. What behavior do you intend in this case?
-
1$\begingroup$ "What behavior do you intend in this case?" There is no confusion here, because what Zeta gives when provided with 1 argument is ok. $\endgroup$– AnixxCommented Dec 20, 2012 at 1:05
-
1$\begingroup$ @Anixx no, it would not.
$PreRead
operates on the Box form of the input expression (read this) and/.
only replaces complete expressions, not sub-strings (read this too). Input such asmyZeta
and"A Zeta String"
are safe from the replacement. $\endgroup$ Commented Dec 20, 2012 at 1:08 -
1$\begingroup$ @Anixx I do not believe that my formulation will have that problem.
$PreRead
is only applied to input and will not cause overhead for internal handling of large expressions. TheMakeBoxes
rule is (normally) only used when producing output and this rule is quite straightforward and should not impact performance significantly in my estimation. $\endgroup$ Commented Dec 20, 2012 at 1:14 -
2$\begingroup$ @Mr.Wizard There's actually an analogous example in the docs. +1 because this does not have the same performance problem my solution has, and for reduced the possibility of breakage. I would still not feel entirely safe about using it though. Consider the following: Type
OneZetaTwo
then change the formatting ofZeta
part (e.g. colour it red). Examine the box form and note that it contains"Zeta"
... this box form is not passed to the kernel, so this example does not break anything. But it does make me uncomfortable. $\endgroup$– SzabolcsCommented Dec 20, 2012 at 1:15 -
1$\begingroup$ So here's an artificial edge case which I would consider breakage. If you enter boxes as string representation into the front end, they're normally just treated as boxes and converted to the expression representation (unless they're preceded by
\!
). So let's enter\(something\)
. It is just the string"something"
, as the box form is just the string in this case. Now let's try\(Zeta\)
... and we get"HurwitzZeta"
. Probably not what should happen ... My solution is immune to this problem BTW ... $\endgroup$– SzabolcsCommented Dec 20, 2012 at 1:35
This should be possible using MakeBoxes
and MakeExpression
, but I haven't found a way which I can confidently say is going to be safe.
So beware, the method below may break things and I do not recommend using it! I haven't noticed any breakage yet, but that doesn't mean it doesn't exist.
Example: suppose we want to use Γ
to write the Gamma
function in standard form. We can create a formatting rule for Gamma
:
MakeBoxes[Gamma, StandardForm] = "Γ"
And a parsing rule for Γ
:
MakeExpression[expr_ /; ! FreeQ[expr, "Γ"], StandardForm] :=
MakeExpression[expr /. "Γ" -> "Gamma", StandardForm]
Now you can do things like this:
Note though that the parsing rule I used is extremely aggressive and it will scan every single expression it encounters for occurrences of "Γ"
. This will surely impact the performance of parsing, how severely, I do not know, but I won't be surprised if someone finds that some operations got much slower. It may also replace something I haven't thought of and break things.
I needed to use this very aggressive rule because MakeExpression
is not applied to strings inside e.g. a RowBox
, only the complete RowBox
. So otherwise it would have been necessary to handle both a lonely string (as the sole input) and strings that appear in all the different types of boxes (RowBox
, GridBox
, and possibly many others I don't know about).
-
$\begingroup$ Agree completely (I think). Perhaps you could use the
MakeExpression[...]/;guard=Block[{guard=False}
trick to avoid the overhead $\endgroup$– RojoCommented Dec 20, 2012 at 3:16
For display purposes, you could use Format
. Say you hate Sin
and want it to appear as Sqrt
:
Unprotect[Sin];
Format[Sin] := Sqrt
Format[Sin[x_], TraditionalForm] := Sqrt[x]
Protect[Sin];
Simplify[Cos[x]*Tan[x]]
FullForm[%]
%% /. x -> \[Pi]/4
Plot[%%%, {x, 0, \[Pi]}, AxesLabel -> {x, Sin[x]}]
So it displays as Sqrt
but is still Sin
-
$\begingroup$ I had no clue you could do this trick with
TraditionalForm
. Nice $\endgroup$– aclCommented Dec 20, 2012 at 0:04
I don't recommend this, but one idea is to use InputAutoReplacements
to automatically convert Zeta
to a tagged version that evaluates to HurwitzZeta
:
CurrentValue[EvaluationNotebook[], {InputAutoReplacements, "Zeta"}] = TagBox["Zeta", HurwitzZeta&]
TagBox["Zeta", HurwitzZeta &]
Then:
Zeta[x, y] //InputForm
HurwitzZeta[x, y]
To complete things, we also need to define a MakeBoxes
rule for HurwitzZeta
:
Unprotect[HurwitzZeta];
MakeBoxes[HurwitzZeta, StandardForm] := TagBox["Zeta", HurwitzZeta&]
Protect[HurwitzZeta];
Then:
Zeta[x, y]
Zeta[x, y]
% //InputForm
HurwitzZeta[x, y]
Here is MrWizard's RSolve
example:
RSolve[f[a + 1] == f[a] - 1/Sqrt[a], f[a], a]
{{f[a] -> C[1] + Zeta[1/2, a] - Zeta[1/2]}}
It is much more difficult to actually enter Zeta[x]
now, but it is possible if you use strings with Symbol
:
Symbol["Zeta"][x] //InputForm
Zeta[x]
A saner alternative more on the lines of Szabolcs answer is to use the greek letter $\zeta$ instead of Zeta
:
CurrentValue[EvaluationNotebook[], {InputAutoReplacements,"zeta"}] = TagBox["ζ", HurwitzZeta&];
Unprotect[HurwitzZeta];
MakeBoxes[HurwitzZeta[a_, b_], StandardForm] ^:= TemplateBox[
BoxForm`ListMakeBoxes[{a, b}, StandardForm],
"HurwitzZeta",
DisplayFunction -> (RowBox[{"ζ", "[", RowBox[{#1, ",", #2}], "]"}]&),
Tooltip->"HurwitzZeta"
]
Protect[HurwitzZeta];
Here is a short animation: