I don’t know, this doesn’t jive with my experience of abstractions.
Yes, structuring code with abstractions rather than just directly doing the thing you’re trying to do makes the code more structurally complex and yes sometimes it is unnecessary and yes more structural complexity means it’s harder to tell what any individual chunk of code does in isolation, but I think your example suggests you’re engaging with abstractions very differently from I do.
When I write code and employ abstraction, it’s usually not that I just think “oh, how could I make this more clever”, it’s that I think, “geez, I’m doing the same thing over and over again here, duplicating effort; I should abstract this away so I only have to say something about what’s different rather than repeatedly doing what’s the same”. Some people might call this removing boilerplate code, and that’s sort of what’s going on, but I think of boilerplate as more a legacy of programming languages where for toolchain reasons (basically every language prior to so-called 4th gen languages) or design reasons (4th gen languages like Python that deliberately prevent you from doing certain things) you needed to write code that lacked certain kinds of abstractions (what we frequently call metaprogramming). Instead I think of this as the natural evolution of the maxim “Don’t Repeat Yourself” (DRY) towards code that is more maintainable.
Because when I really think about why I code with abstractions, it’s not to show off or be efficient with my lines of code or even to just make things pretty, it’s to write code that I can maintain and work with later. Well designed abstractions provide clear boundaries and separation of concerns that make it easy to modify code to do new things as requirement change and refactor parts of the code. Combined with behavioral test driven development, I can write tests to the expected behavior of these concerns, and know I can trust the tests to let me change the code and still pass so long as the behavior doesn’t change, and to let me know if I accidentally break the behavior I wanted in the code.
Yes, I often don’t do it perfectly, but when it works it’s beautiful. My experience is that mainly the people who dislike it are new grads who have spent all their time coding toys who haven’t much had to deal with large, complex systems; everyone seems to understand that learning about system-specific abstractions is just naturally what we must do to be kind to ourselves and future programmers who will work with this code. To do otherwise is to do the future a disservice.
I don’t know, this doesn’t jive with my experience of abstractions.
Yes, structuring code with abstractions rather than just directly doing the thing you’re trying to do makes the code more structurally complex and yes sometimes it is unnecessary and yes more structural complexity means it’s harder to tell what any individual chunk of code does in isolation, but I think your example suggests you’re engaging with abstractions very differently from I do.
When I write code and employ abstraction, it’s usually not that I just think “oh, how could I make this more clever”, it’s that I think, “geez, I’m doing the same thing over and over again here, duplicating effort; I should abstract this away so I only have to say something about what’s different rather than repeatedly doing what’s the same”. Some people might call this removing boilerplate code, and that’s sort of what’s going on, but I think of boilerplate as more a legacy of programming languages where for toolchain reasons (basically every language prior to so-called 4th gen languages) or design reasons (4th gen languages like Python that deliberately prevent you from doing certain things) you needed to write code that lacked certain kinds of abstractions (what we frequently call metaprogramming). Instead I think of this as the natural evolution of the maxim “Don’t Repeat Yourself” (DRY) towards code that is more maintainable.
Because when I really think about why I code with abstractions, it’s not to show off or be efficient with my lines of code or even to just make things pretty, it’s to write code that I can maintain and work with later. Well designed abstractions provide clear boundaries and separation of concerns that make it easy to modify code to do new things as requirement change and refactor parts of the code. Combined with behavioral test driven development, I can write tests to the expected behavior of these concerns, and know I can trust the tests to let me change the code and still pass so long as the behavior doesn’t change, and to let me know if I accidentally break the behavior I wanted in the code.
Yes, I often don’t do it perfectly, but when it works it’s beautiful. My experience is that mainly the people who dislike it are new grads who have spent all their time coding toys who haven’t much had to deal with large, complex systems; everyone seems to understand that learning about system-specific abstractions is just naturally what we must do to be kind to ourselves and future programmers who will work with this code. To do otherwise is to do the future a disservice.