I have some objects represented as follows:
Object[data, param]
data
is a list of numbers, param
is an integer.
Somewhere in my program, I need to do something like that:
pseed = N[seed, prec];
In this context, seed
can be either a number or my object Object
. When seed
is an Object
I want N
to be applied only to data
list. But N
is applied to param
too, which I want always to be an Integer.
Of course, I could write:
pseed = If[Head[seed] === Object,
MapAt[N[#, prec]&, seed, 1],
N[seed, prec]
];
But I believe, this would make my code messy and hard to read. Therefore I decided to do something like that:
Unprotect[N];
N[Object[data_List, param_Integer], p_] := Object[N[data, p], param];
Protect[N];
Than the simple N[seed, prec]
should work whether seed
is Obj
or Number
. However, I get the following error:
$RecursionLimit::reclim: Recursion depth of 1024 exceeded.
I cannot understand, where do I have a recursion?
Thanks in advance!
Update. I have received the answer from Wolfram Support:
I understand you believe you've found a bug with N.
In this case, Mathematica is behaving as designed. N is a fairly complicated function and changing its definition arbitrarily by using the Unprotect function can lead to unforeseen consequences. While the definition we provide works as designed, the change you made to it does not behave as you expect. The TagSet and TagSetDelayed function was supplied to address just the kind of problem you are trying to solve. Try
In[1]:= f/:Verbatim[N][f[arg1_,otherArgs__]]:=f[N[arg1],otherArgs] In[2]:= N[f[1,2]] Out[2]= f[1.,2]
Alternatively, you can avoid the need for the Verbatim function by injecting a secondary step:
In[1]:= f/:NN[f[arg1_,args__]]:=f[NN[arg1],args] In[2]:= NN[arg1_]:=N[arg1] In[3]:= NN[f[1,2]] Out[3]= f[1.,2]
Setting up the dummy function can even allow you to avoid the need for the TagSetDelayed:
In[1]:= NN[f[arg1_,args__]]:=f[N[arg1],args] In[2]:= NN[f[1,2]] Out[2]= f[1.,2]
For more on TagSet, TagSetDelayed and Verbatim, please see
http://reference.wolfram.com/language/ref/TagSetDelayed.html
The question seems to be solved. Thank everybody for participation!