One bright morning, on a stroll through the code base, I encountered a sight which stopped me dead in my tracks and made me recoil with horror. Where I expected to see a set of nested for loops, looping while they loop, I instead was confronted with a horrific archetecture built around the premise that people don't know how to iterate correctly, and the only proper way to do something for every element in a container was to pass in an operation function, which the container would successively apply to each element. I tracked down the sole consumer of this API and it did indeed define a lambda to pass into the iteration function. Upon inspecting the lambda, I saw that it defined another lambda inside of itself, for the container function had nested containers that could only be iterated in this singularly uncommon way. I checked the backing data structures; they are arrays of structs. In order to execute the task of two for loops, the engineer had built in a function-passing archetecture that obscures the fundamental data type being iterated. Don't do this. Write simpler code. People will come to me with all of the reasons why one _might_ want to do such a thing; to protect the user from particularly frightening data structures perhaps, or to permit extra layers of safety. I assure you, none of these cases were applicable; the core functionality could and should have been expressed by iterating via for loop. The code would be simpler, making it trivial to check for correctness, which is what is most important in my industry. Write simpler code. Unless your problem is 100% defined for every case and will never change on you, ever, even after shipping, you should default to making everything as simple as possible. Children should be able to read your code, because after your 68th hour debugging some issue you will wish you still had the cognitive capacity of child. You don't want to be unpacking some clever programmer's puzzle, especially if that programmer is you. Write simpler code. Write for loops. Write long functions unless there is obvious gain from chopping it up into smaller pieces. Consider inlining functions that are only called once. Return early from functions whenever possible. Make variables public until they have a reason to be made private. Keep inheritance hierarchies shallow. Don't write speculative API. Build to the requirements without closing doors on future growth. It is much easier to extend simple code than complex code; overbuilt codebases therefore push you towards a rewrite, rather than continuing to use systems that nobody can understand. Code that can be understood and does its job can last a long time. So you should always strive to make your systems as simple as possible to meet your immediate needs. Write simpler code.