Coroutines: A subroutine is a basement which you go down into and come up from via the same door. A coroutine, by contrast, is an adjacent room with several doors and you can leave temporarily even if you're not completely done in there (of course, you must re-enter whichever door you previously left; not a perfect analogy).
Concurrency: doing multiple things at once. In a kitchen, concurrent actions work best when the cooks either don't share resources or have clever schemes for ensuring there is always an alternative activity to perform if resources are in use. This can be as simple as getting on a list for the knife, or blender, or what-have-you, and you'll be called when it's open.
Caching: I dislike going to the grocery store every time I am hungry so I cache things I will need to make shorter trips on average. How much you cache at once is important to determine.
Regular expression matching: This isn't what I'm trying to find, this is a description of what I'm trying to find.
(When you're painting, for example, you keep pencil, eraser, brush, paints, and palette nearby, because they're in active use and it would take awhile to fetch them every time you needed them.)
Your other examples are great though. I worked in a kitchen for a couple of years and it's definitely all about concurrency.
Either way, thanks. And, your article is fucking brilliant. I might ape its style soon in a few "Learn Perl" articles of my own.
1) '[\d]' means any digit
2) '+' means one or more
3) '[\d]+' means one or more digits
Understanding that is not hard or tricky at all. Using that to build a complicated regular expression is hard.
I think that's the author's point. Understanding the concept of a pointer or recursion is not hard. Actually using those concepts to build something takes practice and hard work.
edit: formatting
Problem solving is difficult. Recognizing how to apply dynamic programming is difficult. NP-completeness proofs are difficult.