8
$\begingroup$

When I try to define this simple function

getCoeff[SeriesData[_, _, coeff_, _, _, _]] := coeff[[2]]

I get an error:

SeriesData: Coefficient specification coeff_ in SeriesData[_,_,coeff_,_,_,_] is not a list.

Can someone explain what's wrong with this? My understanding was that SetDelayed shouldn't complain about such things because until I actually evaluate an expression containing getCoeff it shouldn't try to evaluate Part[coeff,2].

There is no error thrown for the similar function

f[g[_, _, x_, _, _, _]] := x[[2]]

and furthermore getCoeff works as expected:

getCoeff@Series[E^(\[Pi] x), {x, 0, 3}]

outputs $\pi$.

I know the "right" way to manipulate SeriesData, I'd just like to understand this case for its own sake.

$\endgroup$
1
  • 2
    $\begingroup$ Use unevaluated: getCoeff[Unevaluated[SeriesData[_, _, coeff_, _, _, _]]] := coeff[[2]]; Then getCoeff@Series[E^(\[Pi] x), {x, 0, 3}] = \[Pi]. $\endgroup$ Commented Sep 21, 2019 at 21:10

1 Answer 1

10
$\begingroup$

This is due to the special behavior of SetDelayed (:=) with regards to the first argument (see e.g. this question): The arguments of the l.h.s. are evaluated by SetDelayed, which causes the error you are seeing - after all, SeriesData[_, _, coeff_, _, _, _] is not a valid SeriesData construct. This is what HoldPattern is designed for: It prevents evaluation of its argument (like Hold), but is invisible to the pattern matcher. The solution is therefore simply:

(* prevent the l.h.s. from being evaluated *)
HoldPattern@getCoeff[SeriesData[_, _, coeff_, _, _, _]] := coeff[[2]]

getCoeff@Series[E^(π x), {x, 0, 3}]
(* π *)

(* prevent only evaluation of the first argument (equivalent in this case) *)
getCoeff[HoldPattern@SeriesData[_, _, coeff_, _, _, _]] := coeff[[2]]

getCoeff@Series[E^(π x), {x, 0, 3}]
(* π *)

As noted in the comments, the original version works perfectly fine ignoring the error message: If you look at ?getCoeff, you'll see that the definition that was actually made is the same with and without HoldPattern. If you evaluate SeriesData[_, _, coeff_, _, _, _] on its own, you will see that you get the error message, and then the input will be returned (which happens for many Mathematica functions) - if you would have gotten something else back, the definition would not work.

$\endgroup$
2
  • $\begingroup$ Thanks, this helps a lot! However I still wonder: why does the code seem to work anyway? If I left it as it was, would there be any consequences other than the error message? $\endgroup$
    – Diffycue
    Commented Sep 22, 2019 at 16:50
  • $\begingroup$ No, in this case there would be no consequence: If you look at ?getCoeff, you'll see that the definition that was actually made is the same with and without HoldPattern. If you evaluate SeriesData[_, _, coeff_, _, _, _] on its own, you will see that you get the error message, and then the input will be returned (which happens for many Mathematica functions) - if you would have gotten something else back, the definition would not work $\endgroup$
    – Lukas Lang
    Commented Sep 22, 2019 at 17:03

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.