7
$\begingroup$

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?

$\endgroup$
10
  • $\begingroup$ what do you mean by results? do you mean in the help notebooks, for instance? $\endgroup$
    – acl
    Commented 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$
    – Anixx
    Commented Dec 19, 2012 at 23:42
  • 1
    $\begingroup$ What function are you thinking of, for example? $\endgroup$
    – Zviovich
    Commented 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.Wizard
    Commented Dec 19, 2012 at 23:47
  • 2
    $\begingroup$ @PatoCriollo I want Zeta to always refer to HurwitzZeta, both in results and in input. $\endgroup$
    – Anixx
    Commented Dec 20, 2012 at 0:43

4 Answers 4

7
$\begingroup$

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?

$\endgroup$
15
  • 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$
    – Anixx
    Commented 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 as myZeta and "A Zeta String" are safe from the replacement. $\endgroup$
    – Mr.Wizard
    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. The MakeBoxes rule is (normally) only used when producing output and this rule is quite straightforward and should not impact performance significantly in my estimation. $\endgroup$
    – Mr.Wizard
    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 of Zeta 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$
    – Szabolcs
    Commented 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$
    – Szabolcs
    Commented Dec 20, 2012 at 1:35
5
$\begingroup$

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:

Mathematica graphics

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).

$\endgroup$
1
  • $\begingroup$ Agree completely (I think). Perhaps you could use the MakeExpression[...]/;guard=Block[{guard=False} trick to avoid the overhead $\endgroup$
    – Rojo
    Commented Dec 20, 2012 at 3:16
4
$\begingroup$

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]}]

Mathematica graphics

So it displays as Sqrt but is still Sin

$\endgroup$
1
  • $\begingroup$ I had no clue you could do this trick with TraditionalForm. Nice $\endgroup$
    – acl
    Commented Dec 20, 2012 at 0:04
1
$\begingroup$

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:

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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