I agree with your first part entirely. As for the comments about math I look at it this way. Math can usefully be described as a nothing but a bunch of design patterns, discovered and built in just the way you say. Look at the way addition and multiplication morph into a ring, once you learn a little math. Dynamic programming algorithms then work for any ring.
The frustrating thing for programmers is that these patterns don't often seem to be directly useful in computer science. Oops, I mean programming.
I think that is changing thanks to functional languages. One of the most mind blowing CS lessons I learned in the past few years was how to calculate the derivative of a data structure and what to use it for, using plain old calculus rules. Now that might seems useless or crazy if you haven't studied algebraic data types. But these are readily seen to be useful once you learn a little math (and Haskell). In a few years I believe that FP will be credited for the wholesale import of mathematical design patterns into everyday programming. The Haskell and related communities are still small enough that they have only scratched the surface.
> Math can usefully be described as a nothing but a bunch of design patterns, discovered and built in just the way you say.
Well, kinda-sorta. It depends on how you define a design pattern, and how you generalize that definition to mathematics. The way that I define design patterns, I would disagree.
I define design patterns as "an abstracted, re-usable piece of functionality that cannot be made into a library." I think that the non-libraribility is the defining feature of design patterns: it's why you have to learn to implement them, instead of just linking to them like most other forms of re-usable functionality[1]. As soon as you can figure out how to factor that functionality into a library (or template or inheritable class or interface or whatever), it's no longer a design pattern.
When I look at mathematics, I would consider that to be mostly a collection of libraries rather than design patterns. Theorems, obviously, are more like libraries because you can simply plug in the antecedents and get out the sequents without looking at the proof. There are also things like design patterns, techniques that you can apply in related domains. However, mathematicians have a pathological urge to turn these techniques into theorems by proving properties about what they will do and when they can be applied. The result is that math tends to have many libraries but few surviving design patterns at any point.
[1] Note that this definition is language-dependent. It also dovetails somewhat with the "design patterns are evidence of an underpowered language" line of thought, but is distinct because it deals with extensible functionality rather than built-in functionality.
Besides many theorems math does have design patterns; Tim Gowers in his essay "The two cultures in mathematics" argues that part of the reason mathematicians in other fields sometimes think there's not much to combinatorics is that they ate used to having widely applicable insights implemented as theorems whereas combinatorics tends to have them as design patterns.
Your definition of a design pattern is more precise than mine for sure. In FP its not "an abstracted, re-usable piece of functionality" unless it can be made into a library, as far as I know.
But it seems to me that FP forces you to look at programming in terms of what you are doing to transform data. In that case I can't see why having enough libraries won't do the job.
The equivalent to a mathematical result in programming is not a design pattern, it's a program, algorithm, or data structure. Design patterns a la GoF (and the OP) are pseudo-formalisms. They're not well-defined enough to be comparable to math; not even close.
Derivative of a data structure? I never heard of that before, though I'm familiar with derivatives in calculus. How do you calculate the derivative of a data structure? I'm guessing that you start by eliminating values that are constant with respect to some variable, but I'm not sure how you'd reduce the rest. How common is it to have values in a data structure that are non-linearly related to a variable?
You are one the wrong track. You'll be surprised. Look up algebraic data structures and zippers. The partial derivative of an algebraic data structure is its zipper.
The frustrating thing for programmers is that these patterns don't often seem to be directly useful in computer science. Oops, I mean programming.
I think that is changing thanks to functional languages. One of the most mind blowing CS lessons I learned in the past few years was how to calculate the derivative of a data structure and what to use it for, using plain old calculus rules. Now that might seems useless or crazy if you haven't studied algebraic data types. But these are readily seen to be useful once you learn a little math (and Haskell). In a few years I believe that FP will be credited for the wholesale import of mathematical design patterns into everyday programming. The Haskell and related communities are still small enough that they have only scratched the surface.