If you have pairs, these are equivalent. Just set $P$ to $W\times P$ in your version of $d$ and you'll see that at least the types are isomorphic. To use some older FP terminology, the distinction is between a paramorphism and a catamorphism. Now we might say between a recursor and a fold. $c$ corresponds to the following constructor for some data type (using Haskell syntax) which, for clarity, I'll assume is the only constructor:
data W = Constr (A -> W) (B -> C -> W) D W
A fold would then look like:
foldW :: ((A -> x) -> (B -> C -> x) -> D -> x -> x)
-> W
-> x
foldW f (Constr aw bcw d w) =
f (\a -> foldW f (aw a))
(\b c -> foldW f (bcw b c))
d
(foldW f w)
A recursor would look like:
recW :: ((A - W) -> (A -> x) -> (B -> C -> W) -> (B -> C -> x) -> D -> W -> x -> x)
-> W
-> x
recW f (Constr aw bcw d w) =
f aw
(\a -> recW f (aw a))
bcw
(\b c -> recW f (bcw b c))
d
w
(recW f w)
So what's happening here is that we're passing the subterms both recursively processed, like in foldW and unprocessed. Note the f parameter corresponds to the existence of the $d$ function in both your and the book's variant in each of the definitions respectively. It will probably be clearer for a less arbitrary data type.
data N = Zero | Succ N
foldN :: x -> (x -> x) -> N -> x
foldN z s Zero = z
foldN z s (Succ n) = s (foldN z s n)
recN :: x -> (N -> x -> x) -> N -> x
recN z s Zero = z
recN z s (Succ n) = s n (recN z s n)
Note that recN corresponds to primitive recursion, but also note that we're just additionally passing the predecessor to the s function in recN. We can obviously define foldN/foldW in terms of recN/recW. The other way is also not too difficult.
recN :: x -> (N -> x -> x) -> N -> x
recN z s n = snd (foldN (Zero, z) (\(m, x) -> (Succ m, s m x)) n)
recW :: ((A - W) -> (A -> x) -> (B -> C -> W) -> (B -> C -> x) -> D -> W -> x -> x)
-> W
-> x
recW f w =
snd (foldW
(\awx bcwx d (w', x) ->
(Constr (\a -> fst (awx a)) (\b c -> fst (bcwx b c)) d w',
f (\a -> fst (awx a))
(\a -> snd (awx a))
(\b c -> fst (bcwx b c))
(\b c -> snd (bcwx b c))
d
w'
x))
w)
So if you have pairs you can just continue to use initial algebra semantics. Without pairs things are more complicated which is why primitive recursion is a recursor and not a fold which would be more natural from a categorical perspective. It should also be clear why, even with pairs, we usually want to have the recursor rather than the fold as the recursor is easier to use and requires far less computation for many common patterns (e.g. "pattern matching"). To calculate the predecessor of a natural using foldN requires time and space linear in the natural and is slightly non-obvious to write. Using recN, it's constant time and trivial to write.