22
$\begingroup$

I can live with this but I can't figure out why the following is 0:

Derivative[1][f[##] &][x]

0

From documentation for Derivative:

[...] Whenever Derivative[n][f] is generated, the WL rewrites it as D[f[#],{#,n}]&. [...]

but

D[f[##] &[#], {#, 1}] &[x]

f'[x]

So where is this 0 from?

$\endgroup$

2 Answers 2

22
$\begingroup$

I believe there are at least three cases treated separately by Derivative.

1) A function defined by a Symbol. This follows the the rule cited in the documentation.

g[x___] := f[x];
Derivative[1][g][x] // Trace

(*
 { { g'
   , { g[#1]                    <-- Here the rule is being applied
     , f[#1] }
   , f'[#1] & }
 , (f'[#1] &)[x]
 , f'[x] }
*)

2) A function defined by Function, with explicit symbolic arguments. This one cannot mimic f[##] &, but it seems to be a special case not handled in the way explained in the documentation; rather, the body is differentiated directly.

Derivative[1][Function[{x}, f[x]]][x] // Trace

(*
 { { Function[{x}, f[x]]'
   , Function[{x}, f'[x]] }    <-- Differentiates the body
 , Function[{x}, f'[x]][x]
 , f'[x]}
*)

3) A "pure" Function (the OP's case). This also is handled by direct differentiation of the body, with respect to Slot[1]. In the OP's example, the expression does not (symbolically) depend on Slot[1], so its derivative is zero. Apparently, rewriting SlotSequence in terms of Slot, say, in accord with the number of arguments passed to Derivative was either rejected or not considered in the design of Derivative.

Derivative[1][f[##] &][x] // Trace

(*
 { { (f[##1] &)'
   , 0 & }                     <-- Differentiates the body
 , (0 &)[x]
 , 0}
*)

The following is equivalent to my view of how Derivative works:

deriv[n__][f_] := f /. {
   HoldPattern[Function[body_]] :>
     With[{dbody = D[body, Sequence @@ Transpose@ {Array[Slot, Length@{n}], {n}}]},
       Function[dbody]],
   HoldPattern[Function[vars_List, body_]] /; Length[vars] == Length[{n}] :>
     With[{dbody = D[body, Sequence @@ Transpose@ {vars, {n}}]}, 
      Function[vars, dbody]],
   HoldPattern[ff_] :>
     With[{vars = Array[Slot, Length@{n}]}, 
      Evaluate@ D[ff @@ vars, Sequence @@ Transpose@ {vars, {n}}] &]}

deriv[1][g][x]
deriv[1][Function[{x}, f[x]]][x]
deriv[1][f[##] &][x]
(*
  Derivative[1][f][x]
  Derivative[1][f][x]
  0
*)
$\endgroup$
2
  • $\begingroup$ Isn't then documentation wrong? "Whenever" is missleading. $\endgroup$
    – Kuba
    Commented Nov 17, 2015 at 9:01
  • 2
    $\begingroup$ @Kuba, yes. At best it is vague. (What sort of expression does f represent? What it mean by "generated"? "Generated" does not sound like it refers to user input.) $\endgroup$
    – Michael E2
    Commented Nov 17, 2015 at 12:16
11
$\begingroup$

Consider

 Derivative[1][f[##] &] // FullForm

Function[0]

 Function[0][x]

0

So the snippet you quote from the docs might not be entirely accurate; might not be considering such an edge case as ##.

I believe that Derivative is looking for head Slot when detects a pure function goes on to rewrite it, so it ignores head SlotSequence -- i.e., treats it same as it would treat head u in

 Derivative[1][f[u[1]] &][x]

0

$\endgroup$

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.