# How to mock up an "NHoldSubset" property

I have a numeric function f for which I would like the action of N to act only on the last two arguments (and more generally, on any chosen subset of a function's set of arguments).

More concretely, I'd like the following behavior

f[1, 1/2, 1/3, 1/4, 1/6] // N
(* f[2, 3, 4, 1/3, 0.25, 0.1667] *)


Neither SetAttributes[f, NHoldAll], SetAttributes[f, NHoldFirst], nor SetAttributes[f, NHoldRest] will do the job.

I've tried making the definitions the following definitions, the result of calling N[f[1, 1/2, 1/3, 1/4, 1/6]] is summarized after each definition.

(*1*) N[f[a_, b_, c_, d_, e_]] := f[a, b, c, N[d], N[e]];
(* Leads to an infinite recursion, but output is correct *)


and

(*2*) SetAttributes[f,NHoldAll];
N[f[a_, b_, c_, d_, e_]] := f[a, b, c, N[d], N[e]];
(*Same behavior as 1*)


and

(*3*) HoldPattern[N[f[a_, b_, c_, d_, e_]]] := f[a, b, c, N[d], N[e]];
(*N incorrectly applies to all arguments*)


and

(*4*) SetAttributes[f,NHoldAll];
HoldPattern[N[f[a_, b_, c_, d_, e_]]] := f[a, b, c, N[d], N[e]];
(*N fails to apply to any argument*)


Question How do I mock up a behavior of N such that it only applies only to a subset of its arguments?

One idea is to use f[{a, b, c}, d, e] with NHoldFirst. Or, you can try:

ClearAll[f];
SetAttributes[f, NHoldAll];

f/:N[f[a_,b_,c_,d_,e_], def_.] := Module[{new=N[{d,e}, def]},
Replace[new, {x__} :> f[a,b,c,x]] /; new=!={d,e}
]


The condition prevents the infinite recursion.

• This is excellent! I'm improving upon this by using the following: (1) No TagSetDelayed since assignments to N are anyway tagged to the inside symbol. (2) With instead of Module and (3) Apply anonymous Function f[a, b, c, #1, #2] & @@ new instead of replacement Replace[new, {x__} :> f[a,b,c,x]. (not sure about performance improvement on point 3 though). Jun 18, 2017 at 21:52