Live data from Hacker News

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

quuxplusone.github.io

111–120 of 406 posts

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

#111
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…

Finally, the first real example. Every single one so far has been pretty weak.

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

#112
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…

(1) Interfaces / typeclasses / traits are good; inheritance is bad. An object is a family of partially applied functions with some shared state; this means tight coupling between them, rather often unwanted.

(2) Not having mutable state is the point. The more state you have, and the more code paths can mutate the state, the harder it is to reason about the program correctly. Examples of various degrees of hilarity / severity abound.

Sometimes shared mutable state is inevitable for performance reasons. It should be well insulated from other parts of the program then. Same applies to other effects, such as I/O. The standard approach is a core of pure functions with an outer shell of effectful / stateful procedures (as opposed to a mix of them).

While I'm on this soapbox, let me remind that Smalltalk was initially envisioned as an actor system, something like Erlang (hence "messages"), but hardware limitations did not allow to implement the original vision.

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

#113

Earlier quoted context omitted.

None of these situations require an object to do. You can always have a function that takes in an extra ‘state’ argument. You can then do everything you said by passing in the corresponding state values.

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 they have the old headers.

Contrast with C where you would forward declare a struct in the header and pass that around while the definition is hidden in a .c file. This means changes to the size of the structure don't matter because all calling code ever sees is a pointer. (True data hiding!) It's called an opaque pointer and many many libraries use this pattern. e.g. libcairo.

There is then a pattern to do this in C++ called pimpl:

https://en.cppreference.com/w/cpp/language/pimpl

This solves it for C++ but the alleged convenience is gone because now you're coding C++ with the supposed convenience but still your class implementation has to trampoline all the calls to the pimpl which is an extra function call (if you're writing C or C++ this might matter).

But RAII, though. Not having [standardized] RAII sucks.

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

#114
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.

[1] https://developer.mozilla.org/en-US/docs/Web/API/DOMParser

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

#115
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…

It's easy to create an object that pretends to be a function; it's harder to make a function retain state later.

I read that as an argument in favour of functions. Implicit state is pain. Making state explicit is a great advantage of fp-style programming IMHO.

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

#116
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…

Is that true though? You can pass the function itself. If your interface is a function that takes no parameters and returns an int, just wrap this function with another function that takes no arguments and moves the arguments into a closure.

Doing it in a class is forcing these assumptions on your user - that they need this added complexity in all of their uses, and will make for unwieldy code when they don't, or even more unwieldy code when they use a facility that doesn't satisfy the interface you decided on. Let your user be responsible for deciding that and wrapping your code for whatever use they want to do with it - if you write library code (library and not framework), it should be as simple as possible to allow flexibility for the user.

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

#117
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

Do python linters catch that? It is not a code error and sometimes not a design error either, but a warning would be useful, and linters may have the tools necessary for that.

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

#118
post #91

So one of the problems with that function is that it's global. The advantage of having a single class that either has a hidden constructor and only a static function or needs to be initialized but only offers the stateless function is that you know what concept the function is related to. Sometimes I have an entirely stateless class that has a cluster of 10 functions, both private and public just to have that particu…

If you use c++ (as the example in the article) you can just use explicit namespaces at least.

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

#119
post #90

“the count() member function sounds like it should be non-modifying, but in fact it needs to update member data and thus cannot be const” That isn’t correct. Just declare count as mutable . See https://en.cppreference.com/w/cpp/language/cv . Memoization is a valid use case for that feature.

Often it's the motivating example when the feature gets explained.

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

#120
post #92

Earlier quoted context omitted.

If there is state then it makes sense for it to be a class But the parent comment applies

Using init/a constructor implies state, does it not?

I think that depends on what we understand by 'state'. Do we count immutable data? Consider faking a 'bind' with something like:

    var quadrupler = new ConstantMultiplier(4);
    var output = quadrupler.applyTo(42);
The 'quadrupler' instance is stateless in that it's immutable, but it presumably has a (constant) member to store the value 4.
Post reply on HN