This strikes me as just fine unless you're a baker making dozens of kinds of cookies, or if you have a lot of recipes and then suddenly someone becomes allergic to an ingredient, then you have to change dozens or hundreds of things.
I tend toward configuration-driven design, the more I get into operations (not necessarily development in the purest sense).
If I'm writing things that I want people to use, I want them to describe what they want - I don't want them writing code unless they need to extend what I've already done.
That makes sense if it was just a list of ingredients with an identical process in every recipe (in which case the ingredients are simply data) - it may not have been super clear in the article alone, but there was a difference in process between the peanut butter and the oatmeal raisin (think for instance, how many times the .add() was called between the two), which would mean the recipe is acting more like code.
Configuration as code can definitely work and make some things more clear (at least, until the point an edge-case has to be added to the core routines to account for a new/custom type of configuration process).
Using a lisp tends to treat code as data, which solves all the problems in one fell swoop.
I tend toward configuration-driven design, the more I get into operations (not necessarily development in the purest sense).
If I'm writing things that I want people to use, I want them to describe what they want - I don't want them writing code unless they need to extend what I've already done.