Live data from Hacker News

The use of `class` for things that should be simple free functions

quuxplusone.github.io

11–20 of 406 posts

Re: The use of `class` for things that should be simple free functions

#11
post #2

For anyone who wants to post their opinions on whether OOP is good or bad, may I suggest briefly explaining what you consider to be "object-oriented programming"? I've seen in a lot of threads like these, people often end up talking past each other, because one person's idea of what an "object" turned out to be different from someone else's.

I would really love to hear it too. I made some OOP on various programming languages (mainly PHP/Ruby) and where sometimes this is obvious that using OOP is the solution (interfaces, abstract classes etc), sometimes I feel it is completely overkill and I don't even know why I'm using it.

For example recently, as an exercise, I made a little scraper in Python to extract movies data from a website [1]. This could have been done in procedural programming directly (actually the first iteration was like that), but I rewrote the whole thing as a class and I still don't know why. I think it's completely overkill.

If I was doing a scraper for multiple websites related to movies, that would make sense to use classes as they share the same goal and I could make good use of heritage/interfaces/abstract classes. But here, it's not. I read again and again about when to use OOP or not but I still struggle to find most of the times the good decision. It's like I doing it just because it looks "better".

[1]: https://github.com/kinoute/scraper-allocine

Re: The use of `class` for things that should be simple free functions

#12
A lot of time where I just write simple functions, I end up having to wrap them into objects because it is much more convenient when I want to do static polymorphism - sure, that function I'm writing now doesn't need state but then two days after I have to refactor because the next strategy I use does indeed require state. e.g. :

    template
    struct MyAlgorithm {
        F1 f1; F2 f2;
        void operator()(...) { ... f1(whatever); ... f2(whatever); }
    };
you can't just pass functions to F1 or F2, they have to be objects.

I remember this happening to me at least half a dozen times so far so now I just don't waste time and write them as structs with an operator() directly if it's anything that is meant to be used as a callback somewhere.

See also item 46 on Scott Meyers' "Programming with the STL" which points out a few other issues which can arise from using functions.

Re: The use of `class` for things that should be simple free functions

#14
post #3

Also known in python as "if your class has only two methods, one of which is init, it's a function" in the "stop writing classes" https://www.youtube.com/watch?v=o9pEzgHorH0 EDIT: typo, changed link

Or it's a named stateful or immutable data container with validation? You don't always want to use primitive types. But I am not a Python dev.

Python doesn't have private members, so that doesn't help you as much.

Re: The use of `class` for things that should be simple free functions

#15

I'm fairly new to Unity programming in C# and I was surprised a few months ago that everything in C# must be in a class. As far as I can tell there is no such thing as just a function. Now I have I have a class with some static functions in it.

https://stackoverflow.com/a/1027853

In honesty, statics accomplish the same thing.

Re: The use of `class` for things that should be simple free functions

#16

A lot of time where I just write simple functions, I end up having to wrap them into objects because it is much more convenient when I want to do static polymorphism - sure, that function I'm writing now doesn't need state but then two days after I have to refactor because the next strategy I use does indeed require state. e.g. : template struct MyAlgorithm { F1 f1; F2 f2; void operator()(...) { ... f1(whatever); ...…

> struct MyAlgorithm

This is a particularly bad name for your situation. An algorithm is not an object. Why not "my_state"?

Re: The use of `class` for things that should be simple free functions

#17
Single-function classes make sense if you want the computation to happen lazily on-demand (it may be resource-intensive in CPU, GPU, storage, I/O, etc). The class acts as the place to hold the parameters needed for it and the result if/when it is computed. There's nothing wrong with that.

Down the line you may often need the capability to discard the computation to save storage (and maybe re-do it at a later time), at which point it is not even a single-function class anymore.

Re: The use of `class` for things that should be simple free functions

#18
Counter-point: while in many situations this isn't the right approach, it's worth recognizing when this is the right approach, because they can look awfully similar. An example of this is graph searching, e.g. BFS or Dijkstra's algorithm. The typical implementation is a function. But if you make Dijkstra a class, with (say) a function to iterate through nodes, it lets you do several things that would be difficult with a function: (a) you can now re-use the same object for computing distances to multiple vertices, which allows incremental search, (b) you can now fork/copy the object and continue searching on different extensions of the original graph, (c) you can now save & restore the searcher state to pause the search & continue it later, (d) you can do multiple searches across one or more graphs in lockstep. IMHO these are very much not obvious, and to someone who doesn't recognize what's going on, a class for something like BFS will look exactly like an "OO antipattern", when in reality it's actually providing significant additional functionality for more complicated situations.

Re: The use of `class` for things that should be simple free functions

#19
post #17

Single-function classes make sense if you want the computation to happen lazily on-demand (it may be resource-intensive in CPU, GPU, storage, I/O, etc). The class acts as the place to hold the parameters needed for it and the result if/when it is computed. There's nothing wrong with that. Down the line you may often need the capability to discard the computation to save storage (and maybe re-do it at a later time), a…

Yup. As in everything, the INTENT is very important when judging someone's code.

Unfortunately, this makes it very easy to set up strawmen, then add a click-baity title for the perfect gift for "your side".

Re: The use of `class` for things that should be simple free functions

#20

A lot of time where I just write simple functions, I end up having to wrap them into objects because it is much more convenient when I want to do static polymorphism - sure, that function I'm writing now doesn't need state but then two days after I have to refactor because the next strategy I use does indeed require state. e.g. : template struct MyAlgorithm { F1 f1; F2 f2; void operator()(...) { ... f1(whatever); ...…

> struct MyAlgorithm This is a particularly bad name for your situation. An algorithm is not an object. Why not "my_state"?

> Why not "my_state"?

because it's a HN post and not real code ? And it contains the code of the algorithm, in the operator()... function. So my_state would only tell half the story.

When I use it, what do you think makes more sense :

    GameExecutionAlgorithm game_algo;
    next_positions = game_algo(...);
or

    GameExecutionState game_state;
    next_positions = game_state(...);
> An algorithm is not an object.

That is however completely conflating two different things. By that line of reasoning you couldn't write algorithms in e.g. Java or Smalltalk because there everything is an object and "an algorithm is not an object" => "there are no algorithms in Java / Smalltalk".

Objects are just a syntax construct without attached meaning (or, if you did attach one at some point by reading some 1980 OOP book, please detach from it as that only causes confusion).

Post reply on HN