Skip to content
loading...

re: I love writing scripts to solve small problems VIEW POST

TOP OF THREAD FULL DISCUSSION
re: And yet the reason this is possible is because someone did take the time to write nice reusable code. It's just short term thinking vs long term. I...
 

That is true. It's great to have a community that builds so that we can build on top of each other's work.

If there's anything novel in my scripts, I try to package it and make it reusable (at least on the second or third time I'm using it). But quite often it's just like this code above. Trying to make it general would probably make it even harder to read and extend because it would require many levels of abstraction.

There's one thing (a parser for certain type of data) that I've built more times than I care to admit and I'm planning on building it into a library either on Python or Javascript (or both) because I start to have quite a nice grasp of what it takes and how it's supposed to work.

 

Yeah the code in that script does look simple enough that the reusable part seems to have been made for you already. There comes a point at which a thing (library, user interface, car) is good enough that trying to make it better is mostly just rearranging or abstracting things, which only confuses people.

One thing I disagree with that the development community has been promoting lately is this idea of waiting until some code has been duplicated 3 times before you remove the duplication. If you can tell the code you wrote/will write is a good candidate for making reusable and that you will eventually be able to reuse that at some point, it is better to just write/rewrite it in a reusable way from the beginning. Particularly I disagree with the part where people say you won't know what a good abstraction looks like or how it really will be used until you have seen it repeat a few times. Instead I feel the fastest way to a good abstraction is to make it one right away and then look for good opportunities to start reusing it. This will help you to feel the pain of using it as early as possible, giving you feedback more quickly that you can incorporate. I feel the time coming with the most motivation to write it in a reusable way is when you first recognize it is possible, and if you wait until later you are more likely to put it off longer than intended. I also disagree with the reason where people say/imply the first attempt will necessarily be so bad/off as to be a waste of time and effort because I think this is a skill we can and should strive to learn. What I mean is, if you had the ability to write good, reusable code on the first attempt, would that not be the best way and a worthwhile skill to have? To say it is impossible and then to not try is a self fulfilling belief, the only way one can learn this skill is to keep doing it, mess up, and learn and improve.

At some point I'm going to write an article about type oriented programming, which is a way of thinking and coding that very naturally leads to creating reusable code that is so reusable you will actually yearn to reuse it everywhere. It inevitably leads to the discovery of missing core types, in whatever language you are using, that the language or standard library really should have included in itself long ago or from the beginning.

Thank for a great and thoughtful reply, I'll share my thoughts on some of the points you raised.

One thing I disagree with that the development community has been promoting lately is this idea of waiting until some code has been duplicated 3 times before you remove the duplication.

My opinion on this depends a bit on what kind of duplication we are talking about. If it's within a codebase, I totally agree: duplication leads to many issues in maintainability and will eventually cause issues when someone doesn't realize they need to change things in multiple places.

If it's not exactly duplication but the code varies a bit, I'm 50/50. Sometimes it makes sense to parameterize the code but sometimes it creates a situation where the new code is actually harder to read and understand compared to nearly duplicating the code in a couple of places.

When it's about reinventing the wheel in the context of this blog post, I find it useful to reinvent things every now and then a couple of times. It might be that it's never needed again so spending a lot of time making something reusable library upfront can become a wasted time.

Particularly I disagree with the part where people say you won't know what a good abstraction looks like or how it really will be used until you have seen it repeat a few times. Instead I feel the fastest way to a good abstraction is to make it one right away and then look for good opportunities to start reusing it.

Building something and then starting to use it to learn and improve to reach good abstraction is exactly what that statement you seem to disagree with is about. Based on a single use case, we barely ever know the best abstractions or APIs for the generic use case and thus, I think it's a good approach to see what abstractions arise from the usage rather than trying to always define them upfront.

I also disagree with the reason where people say/imply the first attempt will necessarily be so bad/off as to be a waste of time and effort because I think this is a skill we can and should strive to learn. What I mean is, if you had the ability to write good, reusable code on the first attempt, would that not be the best way and a worthwhile skill to have? To say it is impossible and then to not try is a self fulfilling belief, the only way one can learn this skill is to keep doing it, mess up, and learn and improve.

I totally agree with you that this is something we should all strive for. However, though I believe you can become better at it, I don't see this as purely a technical skill. It's rather about realizing our limitations as human beings in predicting future. I believe these ideas in the community stem from the agile movement that promotes the idea that you should not build for the uncertain future.

All in all I think it's about finding the right balance. Sure, we'd be great off if we could spend lots of time building beautiful, generic and reusable code but it's always a tradeoff of losing progress in other places. As we improve as developers, we become better at writing good code but predicting future is still very difficult.

For example in my small script, one thing that could make it more reusable would be to be able to configure in which format and where the episode numbers are. If it only works with Theme A (1) format, it won't be very generically usable.

However, trying to plan for that before knowing what use cases there are will be very challenging. Maybe it's in format of 1 - Theme A, maybe it's Theme A - 1, maybe it's 00001 Theme A and so on. Especially if the names can contain numbers, we cannot just rely on finding any number with regex.

However, if I find myself doing this same thing with very similar directory structures in the future and see it becoming a pattern in use cases, I can definitely parameterize it further to make it more usable. Until that happens, I won't be able to know which direction is the right one.

At some point I'm going to write an article about type oriented programming, which is a way of thinking and coding that very naturally leads to creating reusable code that is so reusable you will actually yearn to reuse it everywhere.

Looking forward to reading it, sounds really interesting!

Thanks for the response. I do agree that ultimately balance is needed and things like this will always be a judgement call. Just one more point I would like to make. One reason why I often like to start writing some reusable code right away, instead of waiting for the different use cases to build up, is I like the way this provides a placeholder for you to evolve the abstraction. So even if it is true that we can't really predict the future and know the different ways something will be used in advance, it is easier to respond to that knowledge as it builds up by already having a place to capture it. It's basically an application of the principal of environmental design, as explained in the book "Willpower Doesn't Work - Discover the Hidden Keys to Success", by Benjamin Hardy. If you make something hard, we tend to put it off, but if you set up the right environment for an activity to be easy, we are much more likely to do it. Environmental design is also about motivating yourself through investment. If you know you have already invested some time and energy in making an abstraction, you don't want that investment to go to waste, so you are more likely to improve and evolve it as needed. But the opposite is also true, if you already invested in making the code work without relying on abstractions, you won't want that investment to go to waste by having to alter it to use an abstraction when it already works and maybe is not too bad as it is. Anyway, I'm speaking in ideal terms and am in no way implying that I or anyone else should operate on this level at all times. I just feel these are ways the development community in general is failing to recognize as areas we should improve in, not because we don't want to improve, but because we don't yet see ways to make this kind of improvement practical. And that is all well and good, recognize your limitations and keep working in a practical and professional way. But at the same time it is good to keep an open mind and occasionally experiment with ways to improve these things that seem like there may not be a good way to improve them.

Forgot to provide another little teaser about a future article. Type oriented programming (TOP) is the core technical practice involved in a software engineering philosophy I call "feedback looped emergence" (FLE). It is used to coax code and software solutions to appear and grow into their truest, purest form, as an emergent property of working on and in a feedback looped system.

code of conduct - report abuse