Skip to main content
4 of 5
add support answer
ktm
  • 539
  • 2
  • 9

Changing the definition of N: unexpected $RecursionLimit::reclim error

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/TagSet.html

http://reference.wolfram.com/language/ref/TagSetDelayed.html

The question seems to be solved. Thank everybody for participation!

ktm
  • 539
  • 2
  • 9