Live data from Hacker News

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

quuxplusone.github.io

121–130 of 406 posts

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

#121

This antipattern is taken to the extreme with the `DOMParser` [1] class in the Browser. The constructor takes no arguments and it has a single instance method that takes produces a result without mutating any internal state. What's worse, the method returns a newly created object of another class, which in my head is an indication that maybe, just MAYBE it should have been a constructor of said other class instead. […

As it says in the HTML Standard[0]:

>The design of `DOMParser`, as a class that needs to be constructed and then have its `parseFromString()` method called, is an unfortunate historical artifact. If we were designing this functionality today it would be a standalone function.

[0]: https://html.spec.whatwg.org/multipage/dynamic-markup-insert...

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

#122

Earlier quoted context omitted.

Why? You would never suggest this if OO wasn’t the predominant paradigm. What is the benefit of implicitly passing the parameter? I prefer to see it passed explicitly, so the implicit passing is a downside to me, not a benefit.

The benefit is encapsulation.

Encapsulation's a weird one. It's a cornerstone of OO but most/all OO languages have rubbish support for ABIs so changing your object in one library means you need to recompile your code using the library. This is the opposite situation that encapsulation seems to promise (in my view).

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

#123

This antipattern is taken to the extreme with the `DOMParser` [1] class in the Browser. The constructor takes no arguments and it has a single instance method that takes produces a result without mutating any internal state. What's worse, the method returns a newly created object of another class, which in my head is an indication that maybe, just MAYBE it should have been a constructor of said other class instead. […

The browser could be seen as a special case, as it's the most public API around. So classes are in many cases simply for namespacing and modularisation.

Interestingly, the HTML spec for DOMParser has a note about exactly your comment: https://html.spec.whatwg.org/multipage/dynamic-markup-insert... (scroll up 2 lines)

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

#124

Earlier quoted context omitted.

But if you're passing a state object around, you might as well use a class, no? Admittedly simplifying a bit, an instance method is a function that implicitly takes "this" as the first argument.

Why? You would never suggest this if OO wasn’t the predominant paradigm. What is the benefit of implicitly passing the parameter? I prefer to see it passed explicitly, so the implicit passing is a downside to me, not a benefit.

If it's already explicitly part of an object, do you need to be explicit about the same thing twice?

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

#125
post #74

Earlier quoted context omitted.

And if you have many methods, but only one 'public' method, use a closure.

I think before you do that, you should be careful to ask why the methods are private. Frequently, code like that exists because the private methods are reusable code that is not related to the title of this class. So the solution is first to make the private methods into public methods on separate classes. And then the resulting classes probably meet some other rule that says "reduce trivial classes to pure functions…

If the code could be extracted into generic top-level pure functions, I generally don’t unless its used in more than once in the codebase. Otherwise I find a number of contextless generic functions/classes without any idea of their use exhausting to look at eventually.

I have some functions that live in closures that are fairly generic. I’m always contemplating extracting them into a higher level. But they’re currently only used in one place, and they currently reside close to that one place, and this seems sensible.

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

#126

Earlier quoted context omitted.

But if you're passing a state object around, you might as well use a class, no? Admittedly simplifying a bit, an instance method is a function that implicitly takes "this" as the first argument.

Let's use C and C++ as an example. What does the code look like? myobj.cool_func(1,2,3); // C++ cool_func(myobj, 1, 2, 3); // C Is this better? If you use a vanilla C++ style class then the class definition is in the header. All changes to the class require a recompilation and break the ABI of the class. This means you basically cannot release patch versions of your library because consumers cannot link against it if…

> This means you basically cannot release patch versions of your library because consumers cannot link against it if they have the old headers.

This is pretty much only a problem in C/C++ though. Everyone else is using static linking (which you can of course also do in C++), or a VM of some form. IMO relying on a library having stable ABI is a bit of anti-pattern. It's like relying on the implementation details of a function/class rather than it's API: sometimes it's necessary, but it should be avoided if possible.

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

#127
post #76
post #42

Earlier quoted context omitted.

I have a few little classes that are clients for network services. They have a constructor which sets up an HTTP client or socket or something, and maybe prepares some metadata, and then a method to make a call to the service. I could write these clients as lambdas or nested functions which close over the stuff which init creates. But why? An object makes it much clearer that there is state.

I agree. I think of this as a functor pattern: object that supports some params being bound at constructor time, and other params set when the function is called later. In languages that let you operator overload function call syntax, you end up with an object that, once constructed, supports being called like with same syntax as a function call. This works easily in python (define __init__ and __call__ ), and you do…

> I agree. I think of this as a functor pattern: object that supports some params being bound at constructor time, and other params set when the function is called later.

> Another perspective of the whole thing is that you have a function with many arguments, then you curry to bind some arguments, then pass the resulting function with remaining free arguments to be called.

It's not the same, though, because a socket etc is being constructed in the constructor. Here's an abridged (and possibly wrong!) version of a monitoring client:

    class Monitor:
        def __init__(self, monitoring_url, app_name):
            self.monitoring_url = monitoring_url
            self.session = aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=1))
            self.details = ujson.dumps({'app_name': app_name, 'pid': os.getpid()})

        async def send(self):
            async with self.session.post(monitoring_url, data=self.details, raise_for_status=True) as resp:
                pass
If you treat that as currying, you will create a new ClientSession every time you call ping(). A ClientSession contains a connection pool, so that means you will create a new socket instead of reusing one.

> In languages that let you operator overload function call syntax, you end up with an object that, once constructed, supports being called like with same syntax as a function call. This works easily in python (define __init__ and __call__ ), and you don't have to fight the typesystem to structure code that will accept both a callable object or a function.

In Python and Java, you can easily refer to bound methods to produce callables from objects, so this seems like unnecessary work.

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

#128
post #95

Reducing OOP to implementation detail features will yield poor results. The flexibility stems from an improved means of analysis in that types and entities can be identified more easily. By using classes and objects you're retaining flexibility because they can be interchanged; It's easy to create an object that pretends to be a function; it's harder to make a function retain state later. The example is nice; it remo…

Why not make max or pow an object then? If you can model something as a pure function, then it should be a function. You can always add memorization later, if needed. OOP is fundamentally different from FP, objects are not just higher order functions, they are also coalgebras. There is no need to force every peg into a coalgebra hole.

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

#129

Earlier quoted context omitted.

> 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 c…

>When I use it, what do you think makes more sense : > (...) None of your examples make any sense to me. Why not name it simply "game"?

So there are 3 hard problems in programming.

1. Naming things, and .. I forget what the other one is.

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

#130
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 think the object-oriented paradigm, is the most hated aspect:

- "Object-Oriented design" ( class diagrams, use case diagrams, Abbott Textual Analysis... and all the bike bikeshedding fun of UML, Rational Unified process..) generally pushed by the likes of IBM, Oracle, and heavily taught in SE courses.

- a watered-down version of the above, where formalism is discarded, but the first problem-solving step is to decompose the system into classes. an infamous example is the chess-board interview. I think the author is criticizing this part.

I think the majority of people don't hate things like vector or set, despite them being classes.

Post reply on HN