Hey, Charles, thanks a lot for your feed back. In the future I want to make a detailed article with examples, exceptions for each point, and concerning your suggestion on point 3 (Follow DRY as much as possible), if you could already provide me an example of exception (no matter of language, preferably python or javascript), in which the use of repetition is more judicious and allows to have a better code than to follow DRY, it would be really cool. Thanks in advance.
I work with learning methodologies, teach, write curricula, coach, manage, mentor, consult, speak publicly, polemicize, and sometimes work as a full-stack web developer, architect, and web ontologist.
I don't really have a lot of spare time to dig up specific examples, but to be more clear, the trade off is between multiple components/functions/etc. (wet) and more configuration, or maybe layers of indirection and composition ("dry").
One app that I am occasionally forced to work on is abstracted to the point of absurdity. No component, no function, can be for a simple use. If there are ten components, then every bit of commonality must be factored out into another component and then reused. At each level as things are abstracted, they become, well, more abstract -- that is, more generic. This makes them simultaneously more powerful and less useful.
There have been times when I have needed to change one minor thing in that app, and have gone to the file where the actual component lives, only to find that it uses some more abstracted component to do the work. But on finding the file to that component, I find that it abstracts still further to another component. But then that component uses some utility -- say a GraphQL query -- and when I look up the query function, I find it wraps a function that wraps a function that sometimes wraps yet another function.
For a simple fix that should have taken a few seconds, I've now spent half an hour and tracked things back through a dozen files and I still don't understand what the hell all this code is supposed to do!
The actual problem was simple and could have been handled right in that component, but in an attempt to be ultra DRY, the coders made it so complex as to be unusable. And even the coders who made this mess complain about it.
In short, do things in your code as close as possible to where they are needed, and only abstract out functionality when it truly is duplicated and reusable -- and then only raise that abstraction to the level where the branches that use it meet. Except, of course, for general utilities such as pipe or not.
Imagine this: Your front end uses components, no? So why not go all the way and have ONE component (call it Component) and just add a lot of optional props and branching code. Then you only ever have to write the component once, right? How dry is that?
I hope that helps a little. But the easiest way to understand it is just to resist drying up your own code until it is obvious that you have to. You will be surprised how often you really didn't need it any drier.
Yep, I see your point. Too much lvels of abstractions will make the code difficult to comprehend and then to maintains, and simple code is most of the time better even if sometimes it seems to take more lines of code, or have few redundancies.
I work with learning methodologies, teach, write curricula, coach, manage, mentor, consult, speak publicly, polemicize, and sometimes work as a full-stack web developer, architect, and web ontologist.
Exactly. The point of all programming is to take complex problems and break them down into progressively simpler chunks until they are understandable and easily solved. Then those bits are recombined to solve the larger problem.
Approaches that make the code more complex and difficult to understand are the precise antithesis of what programming should be. A variation on Occam's Razor is apropos: as simple as it can be and no simpler.
The majority of modern coding practices (IMO) start off with the right idea: making things simpler. But then they go off track trying to please everyone and soon they have become the problem rather than the cure.
Never write a line of code until you have to.
Never add a dependency except as a last resort.
Never abstract your code any more than absolutely necessary.
Not only will this keep your code simpler and more understandable, but it will save quite a bit of time once you learn the habit (until you learn it, plan on lots of refactoring as you realize you ain't gonna need it).
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Hey, Charles, thanks a lot for your feed back. In the future I want to make a detailed article with examples, exceptions for each point, and concerning your suggestion on point 3 (Follow DRY as much as possible), if you could already provide me an example of exception (no matter of language, preferably python or javascript), in which the use of repetition is more judicious and allows to have a better code than to follow DRY, it would be really cool. Thanks in advance.
I don't really have a lot of spare time to dig up specific examples, but to be more clear, the trade off is between multiple components/functions/etc. (wet) and more configuration, or maybe layers of indirection and composition ("dry").
One app that I am occasionally forced to work on is abstracted to the point of absurdity. No component, no function, can be for a simple use. If there are ten components, then every bit of commonality must be factored out into another component and then reused. At each level as things are abstracted, they become, well, more abstract -- that is, more generic. This makes them simultaneously more powerful and less useful.
There have been times when I have needed to change one minor thing in that app, and have gone to the file where the actual component lives, only to find that it uses some more abstracted component to do the work. But on finding the file to that component, I find that it abstracts still further to another component. But then that component uses some utility -- say a GraphQL query -- and when I look up the query function, I find it wraps a function that wraps a function that sometimes wraps yet another function.
For a simple fix that should have taken a few seconds, I've now spent half an hour and tracked things back through a dozen files and I still don't understand what the hell all this code is supposed to do!
The actual problem was simple and could have been handled right in that component, but in an attempt to be ultra DRY, the coders made it so complex as to be unusable. And even the coders who made this mess complain about it.
In short, do things in your code as close as possible to where they are needed, and only abstract out functionality when it truly is duplicated and reusable -- and then only raise that abstraction to the level where the branches that use it meet. Except, of course, for general utilities such as
pipeornot.Imagine this: Your front end uses components, no? So why not go all the way and have ONE component (call it
Component) and just add a lot of optional props and branching code. Then you only ever have to write the component once, right? How dry is that?I hope that helps a little. But the easiest way to understand it is just to resist drying up your own code until it is obvious that you have to. You will be surprised how often you really didn't need it any drier.
Yep, I see your point. Too much lvels of abstractions will make the code difficult to comprehend and then to maintains, and simple code is most of the time better even if sometimes it seems to take more lines of code, or have few redundancies.
Exactly. The point of all programming is to take complex problems and break them down into progressively simpler chunks until they are understandable and easily solved. Then those bits are recombined to solve the larger problem.
Approaches that make the code more complex and difficult to understand are the precise antithesis of what programming should be. A variation on Occam's Razor is apropos: as simple as it can be and no simpler.
The majority of modern coding practices (IMO) start off with the right idea: making things simpler. But then they go off track trying to please everyone and soon they have become the problem rather than the cure.
Never write a line of code until you have to.
Never add a dependency except as a last resort.
Never abstract your code any more than absolutely necessary.
Not only will this keep your code simpler and more understandable, but it will save quite a bit of time once you learn the habit (until you learn it, plan on lots of refactoring as you realize you ain't gonna need it).