7

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?

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
Anixx
  • 3,585
  • 1
  • 20
  • 32
  • what do you mean by results? do you mean in the help notebooks, for instance? – acl Dec 19 '12 at 23:39
  • @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. – Anixx Dec 19 '12 at 23:42
  • 1
    What function are you thinking of, for example? – Zviovich Dec 19 '12 at 23:44
  • Related: http://mathematica.stackexchange.com/q/117/121 ; http://mathematica.stackexchange.com/q/4281/121 also Exposing Symbols to $ContextPath – Mr.Wizard Dec 19 '12 at 23:47
  • You can't rename/reassign all built-ins — for instance, it's not possible with Evaluated, Unevaluated or Sequence. For the rest, the Attributes are not transferred if you simply use Set and you'll have to make sure they are. – rm -rf Dec 19 '12 at 23:51
  • Please give examples of the substitution you wish to make. It does affect the method one might use. – Mr.Wizard Dec 20 '12 at 00:04
  • 2
    @PatoCriollo I want Zeta to always refer to HurwitzZeta, both in results and in input. – Anixx Dec 20 '12 at 00:43
  • @Anixx so you want to use the alias in input as well? – acl Dec 20 '12 at 01:15
  • @acl yes, of course. – Anixx Dec 20 '12 at 01:22
  • @Anixx then it makes sense to say that in the question (at the moment it's asking for the name to appear in the results, which isn't the same) – acl Dec 20 '12 at 01:25

4 Answers4

7

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?

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • Good but would not it replace ANY occurence of "Zeta" in input with "HurwitzZeta", even in text strings? – Anixx Dec 20 '12 at 01:04
  • We answered nearly simultaneously. – Szabolcs Dec 20 '12 at 01:05
  • 1
    "What behavior do you intend in this case?" There is no confusion here, because what Zeta gives when provided with 1 argument is ok. – Anixx Dec 20 '12 at 01:05
  • 1
    @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. – Mr.Wizard Dec 20 '12 at 01:08
  • But Szabolcs seys it will slow down the parcing and evaluation considerably? – Anixx Dec 20 '12 at 01:11
  • 1
    @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. – Mr.Wizard Dec 20 '12 at 01:14
  • 2
    @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. – Szabolcs Dec 20 '12 at 01:15
  • @Anixx My solution is slightly different. This one won't have the performance problem and it's less likely to break things (at least as long as you're using StandardForm), but I am still not completely comfortable doing this. See my comment above. – Szabolcs Dec 20 '12 at 01:16
  • @Szabolcs interesting point, but the styled substring still does not (and should not) appear as a complete token "Zeta" in the box form. Please let me know if you find an example that breaks this approach. – Mr.Wizard Dec 20 '12 at 01:19
  • I also want any occurencies of Zeta of two arguments in output first to convert to HurwitzZeta and then renamed so not to have a mix of standard Zeta and renamed HurwitzZeta in output... – Anixx Dec 20 '12 at 01:24
  • @Mr.Wizard Regarding your last comment, the "does not" part is true in this case, but I'm not so sure about the "should not" part. It is not documented that it should not be passed to the kernel in that form, so I am simply not comfortable enough about it. Someone may have programmed some part of the system in such a way that these things (both my and your solutions) will break something. – Szabolcs Dec 20 '12 at 01:33
  • 1
    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 ... – Szabolcs Dec 20 '12 at 01:35
  • ... but I still consider your solution to be safer than mine as I can imagine more things going wrong with mine (plus there's the performance hit) – Szabolcs Dec 20 '12 at 01:36
  • @Szabolcs That's a fringe use that I have to say I did not consider. I almost never use that form and I'd never really considered the Box form as seen by $PreRead in that case. Thanks for pointing it out. – Mr.Wizard Dec 20 '12 at 09:07
  • @Anixx re: "I also want" I think that aspect is sufficiently covered here: (1), (2). If you disagree or have problems implementing it please ask. Otherwise I shall read the Accept (thanks) as meaning that the matter is concluded. – Mr.Wizard Dec 20 '12 at 09:14
5

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

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263
  • Agree completely (I think). Perhaps you could use the MakeExpression[...]/;guard=Block[{guard=False} trick to avoid the overhead – Rojo Dec 20 '12 at 03:16
4

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

acl
  • 19,834
  • 3
  • 66
  • 91
1

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

Carl Woll
  • 130,679
  • 6
  • 243
  • 355