Hacker News new | ask | show | jobs
by t43562 696 days ago
I like to start with a fairly unambitious bit of procedural code and gradually introduce abstractions when it starts to get complicated or repetitious.

Straight code becomes functions, occasionally a group of functions cry out to become a class.

In C++ this is a huge effort to do - change hurts more there. In python it's much less painful and I end up with a program that is some imperfect composite of object oriented with functions. Next week when I want it to do more I move it further down the road to structure.

I also like keeping side effects in their own ghettos and extracting everything else out of those if possible but I'm not a big functional programming person - it's just about testing. Testing things with side effects is a pain.

2 comments

I find that JS/TS also lends itself towards this in terms of Node/Deno/Bun usage for apps. You can have a file/module that simply exports a function, a collection of functions, a class, etc. It's easy to keep it simple and then combine with a mix of procedural, functional and oo concepts as best fits the use case.
Yes, I'm doing that a lot, too. I'm often astounded how hostile some languages are to later changes - e.g. java always feels resistant to change, while dotnet and especially python are more amenable. I.e. I totally transformed a program from function to oo in python without much sweat - would have been a total pain in dotnet or java
Can you give examples for what you changed?
Difficult on mobile and I'm without access to k PC ATM.

Basically, my predecessor hat build a python program which had N modules which where applied to a data structure - maybe think of correction steps. First spell checking, than turn manual headlines into actual headlines etc. Originally, they operated on a global data structure, and every new module required calling it on the global structure, so extension was difficult. Worse, every module hat internal state, e.g. the number of spelling mistakes. Reporting these things at the end was cumbersome. There where "required" functions in each module, but it was difficult to newcomers to discover who they where. We changed it so that every step was a class which inherited from a base class, so adding a new step was as easy as inheriting from the base class. Furthermore, we added Auto discovery, so just adding the class in a module was sufficient to get it executed.