News for hackers. Stuff that matters.
Re:The use of `class` for things that should be simple free ... by dataflow on Thursday May 28, 2020 @02:46AM (#23334233)
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 ... by amw-zero on Thursday May 28, 2020 @03:49AM (#23334618)
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.
Re:The use of `class` for things that should be simple free ... by JoeAltmaier on Thursday May 28, 2020 @08:27AM (#23336436)
Sure, you can build your own object and pass the 'this' pointer around manually. You could use C for everything, and tediously do everything again that objects do for free.

But why?

There's a lot of object-hating going around. Its silly. Use objects to encapsulate functionality, they are good at that and everybody understands what it means.

Re:The use of `class` for things that should be simple free ... by amw-zero on Thursday May 28, 2020 @09:13AM (#23336832)
You don’t agree with an idea so it’s silly? Passing around state via variables is no more tedious than the extra syntax for class definitions, constructors, member variable access, extra semantics related to objects, extra keywords related to visibility, etc.

You can encapsulate functionality without objects. There is nothing that you can do with an object that you can’t do with a closure, and the closure version will be 1/10th the size and have 1/10th the semantic programming language elements. That is why you see ‘object-hating’ all over the industry. It hasn’t lived up to its promise.

Objects aren’t simpler, inherently. It’s just what you know, today, and you’re unwilling to acknowledge your biases.

Re:The use of `class` for things that should be simple free ... by munchbunny on Thursday May 28, 2020 @12:06PM (#23338905)
the closure version will be 1/10th the size and have 1/10th the semantic programming language elements

This seems pretty central to your point, but a factor of 10 is also a very strong claim. I'd like to see sources.

Passing around state via variables is no more tedious than the extra syntax for class definitions, constructors, member variable access, extra semantics related to objects, extra keywords related to visibility, etc.

So instead of doing objects, you're doing closures that act like objects?

Re:The use of `class` for things that should be simple free ... by dkersten on Thursday May 28, 2020 @02:10PM (#23340419)
> So instead of doing objects, you're doing closures that act like objects?

No, I'm using using as-plain-as-possible data structures for my state, that I pass to functions that operate on it and return new state. Simple, composable, easy to test, easy to pass the state data elsewhere, serialize it or whatever else I might want to do. I'm not arguing against using classes or objects, but often its unnecessary and hiding mutable state in an implicit "this" variable is, in my opinion, something that often gets in the way of simplicity, as it often tends to imply mutable objects when in my opinion mutable data should be a careful decision rather than the default. Not necessarily of course, but even when you're operating on a constant "this", I feel that hiding the data that its acting on internally is still often not the right choice, especially if the object itself isn't constant/immutable: then its a coeffect instead of an effect, and if you're using truly immutable objects, then its really just a minor syntax difference to write obj.foo(bar) instead of obj(foo, bar). Object systems still carry around a whole bunch of other functionality that you may not want or need, but by using objects, a reader can't know if you are or not without reading the code or documentation. If its data and functions, it isolates the places things can happen somewhat. Classes and objects have their place, but I feel they shouldn't always be the default choice, just because.

That's my take at least, and a big reason I switched from Python and Java to Clojure, but to each their own :)

Re:The use of `class` for things that should be simple free ... by munchbunny on Thursday May 28, 2020 @03:50PM (#23341732)
Fair enough. I agree with you that: "Classes and objects have their place, but I feel they shouldn't always be the default choice, just because."

Often the best things to do in an OOP language is to remember that you don't have to encapsulate everything, and sometimes it's just about bundling data/state.

I may have highlighted the wrong point that I was responding to. I was making a point about the behavioral equivalence of objects and closures in response to this:

There is nothing that you can do with an object that you can’t do with a closure, and the closure version will be 1/10th the size and have 1/10th the semantic programming language elements. That is why you see ‘object-hating’ all over the industry. It hasn’t lived up to its promise.

If you're using a closure where it would have made sense to use an object, it's likely that the closure has the same problems to solve with encapsulation, reasoning about hidden state, etc. that make many languages' object related syntax complex, but instead of dedicated object syntax sugar you're solving it with dedicated closure syntax sugar.

Re:The use of `class` for things that should be simple free ... by dkersten on Friday May 29, 2020 @08:10AM (#23348993)
I agree with you. The only point in favour of using a closure that I want to point out (you already pointed out a big point in favour of objects: the dedicated and streamlined syntax) is that its a more a la carte way of doing objects: you choose how deep you want to go.

Of course in reality its not that bad because you can also use classes as much or little as you want and can use them simply for single dispatch, or namespacing, if you wish.

I do find that in practice syntax and features matter because they push you to think in a certain way and it can be hard to break away from that. For example, I write a lot of Clojure and really like functional languages, but when I use Java, Python or even C++, its all too easy to slip into the OOP mindset even when I set out to just "do functional" in those languages. Maybe that's my failing and its certainly not OOP's fault, but I think in practice (at least from observation) it seems most people are like this.

But yeah, I don't actually disagree with you on what you said.

Re:The use of `class` for things that should be simple free ... by skratlo on Thursday May 28, 2020 @01:37PM (#23340090)
You're saying what? Doing objects that act just like closures? :)
Re:The use of `class` for things that should be simple free ... by munchbunny on Thursday May 28, 2020 @01:54PM (#23340263)
I didn't spell it out, but the gist of it is that their behavioral equivalence means that they also share the same problems, and therefore closures aren't an obviously superior choice (regardless of the syntactic sugar aspect of the debate) the way the parent comment portrays it.
Re:The use of `class` for things that should be simple free ... by chrisrichard on Sunday May 31, 2020 @10:22AM (#23369747)
OO - data with functions

Closures - functions with data

Re:The use of `class` for things that should be simple free ... by TheOtherHobbes on Thursday May 28, 2020 @04:35PM (#23342211)
There's nothing you can do in Python that you can't also do in assembler. It just takes a bit longer to code, but runs a lot faster.

But no one is going to write a big industrial project in assembler today, because it's the wrong abstraction for the job.

Likewise with objects. They make it easy to switch conceptual levels in a domain in a way that projects don't. They take a bit longer to code, but with careful coding you can reuse them ad lib.

The OP is making the point that OOP is the wrong abstraction if there's no reuse. And that's perfectly true.

But there are situations where you want to say "Make a thousand of these items which respond dynamically and somewhat independently to their environment but which still support some kind of top-down management..."[1]

You're going to have a bad time trying to do that with exclusively with closures. Of course you can probably make it work - but that doesn't mean you should.

[1] E.g. particle and/or crowd simulation in games/CGI.

Re:The use of `class` for things that should be simple free ... by woah on Thursday May 28, 2020 @10:41AM (#23337853)
Seems like kind of a meaningless gesture to pass in your own “this” just because you don’t like OOP. If you need a class, why not write it the idiomatic way?
Re:The use of `class` for things that should be simple free ... by nightski on Thursday May 28, 2020 @10:51AM (#23337963)
I didn't down-vote you, but in my opinion it's not meaningless because it makes it inherently more testable. Try testing an opaque class without any accessibility into its state. It is much more difficult. If it takes in the state, performs an operation, and returns a new version of that state (ideally an immutable copy) then it becomes much easier to test and validate.

The reason information hiding is/was advocated was for reduced coupling. But in reality I find that this coupling becomes implicit which is arguably worse. But this is just my opinion.

Re:The use of `class` for things that should be simple free ... by munchbunny on Thursday May 28, 2020 @12:19PM (#23339071)
I see your point, but I 80% disagree with your conclusion.

When you test opaque objects, you're generally not trying to test individual state transitions, you're trying to test that the class's interface adheres to the external promises it makes.

That said, many OOP languages have solutions specifically for when you actually do need to test those internal state transitions. C# for example has the "internal" keyword and allows you to declare friend assemblies, so you mostly get your cake and eat it too, at the cost of not hiding the code from yourself as the module implementer.

Re:The use of `class` for things that should be simple free ... by NoodleIncident on Thursday May 28, 2020 @03:08PM (#23341111)
I interpreted the top-level comment as a list of extra external promises you could add to your class's interface (incremental search, save/restore, etc). If those are easier to test with functions and a state parameter, it might be better to skip the class.
Re:The use of `class` for things that should be simple free ... by sixcorners on Thursday May 28, 2020 @11:29AM (#23338442)
Isn't how you pass things into a function separate from whether you are hiding information? If your state parameter was an opaque pointer then you wouldn't necessarily be able to do anything with it. Also if your class internals were public you would be able to change anything you wanted.
Re:The use of `class` for things that should be simple free ... by nightski on Thursday May 28, 2020 @11:45AM (#23338634)
Exactly! You don't need classes to obtain information hiding. In general treating the state as an opaque pointer is a good thing. But the state is part of the public API whether you want it to be or not. Even if you try to "hide" it in the OOP sense, the result of the methods depends on the internal state so it is leaked through the behavior of those methods.

However, when it is hidden in the OOP sense it makes it much harder to reason about the behavior of a function without reading the source code. Because there is this internal "hidden" state that you do not know exists.

But a referentially transparent function is much easier to understand. For a given input, you get an exact output.

Re:The use of `class` for things that should be simple free ... by kyralis on Thursday May 28, 2020 @12:08PM (#23338938)
You're talking yourself in circles. Your final sentence contradicts the remainder of your point.

Testing is limited when you do not have the ability to fully control state, and understanding can be limited when information is hidden. The impacts of this are determined by the information being hidden, its relationship to the function's behavior, and the documentation of that behavior relative to the calling context.

Limitations on the ability to fully control state are orthogonal to the method of information hiding (opaque function parameters, internal object state, etc).

This is not an OOP/functional discussion, this is a discussion about the tradeoffs inherent in information hiding. And let's be perfectly clear here: These are tradeoffs, not black and white clear wins in either direction.

Re:The use of `class` for things that should be simple free ... by nightski on Thursday May 28, 2020 @01:22PM (#23339930)
I think information hiding is the wrong term. It should be hidden for modification, open for inspection. Functional programming naturally promotes this. OO does not. That's my opinion.

It's been a useful discussion though so I appreciate everyone's input.

Re:The use of `class` for things that should be simple free ... by sixcorners on Thursday May 28, 2020 @02:05PM (#23340366)
So are you saying you no longer think OO inherently makes things harder to test?

I feel like it's difficult to talk about this without examples. The library I like thinking about when I think of passing around in a state variable is the lua C api.

https://www.lua.org/pil/24.1.html here is an example.

https://pgl.yoyo.org/luai/i/lua_State here are docs for the state variable's type.

This is pretty object oriented except that it's not using C++'s syntax sugar. You can't really do much with L except pass it into other lua "methods". The discussion up until your comment seems to be about the difference between using the syntax sugar and passing around a state variable yourself.

Information hiding and these other implementation details are kind of seperate. In my example you can't just configure L exactly how you want by messing around with it or inspecting its state directly. You have to go through accessor "methods".

I think if the argument is that OO promotes information hiding I can agree with that. I'm not sure about the point about the internal state becoming a part of the API though. APIs are contracts that can be met with different implementations right? If your implementation details are public then your contract is huge and inflexible.

Re:The use of `class` for things that should be simple free ... by nightski on Friday May 29, 2020 @12:13PM (#23351808)
Not exactly, I'm saying OO still makes it hard to test because it is an opaque blob of state. It would be really hard to use/test the LUA API for example without knowing it is using a stack underneath the hood. That detail leaks through the API whether you want it to or not. If it was switched to a FIFO queue that would completely change the behavior.

Since using this API makes an implicit constraint that it is using a stack underneath the hood, why not just expose the stack for inspection? What advantage does keeping it an opaque blob have? I agree you don't want code manipulating this stack (although if it is immutable as in FP this isn't an issue), but since the external code already knows it is a stack and relies on that fact then it is part of the public API already.

Re:The use of `class` for things that should be simple free ... by cessor on Friday May 29, 2020 @04:32AM (#23347650)
The term information hiding used in this thread is very confusing (to me, at least).

I believe David Parnas introduced it in 1971 to mean that a program's design was sliced along shared units of concerns (things that vary together) rather than "steps in a flowchart".

https://prl.ccs.neu.edu/img/p-tr-1971.pdf

I believe what you are trying to convey is called "data abstraction", as for example used by Reynolds, 1975;

mentioned here: https://www.cs.utexas.edu/~wcook/papers/OOPvsADT/CookOOPvsAD...

explained here: https://link.springer.com/chapter/10.1007%2F978-1-4612-6315-...

Re:The use of `class` for things that should be simple free ... by sgift on Thursday May 28, 2020 @11:04AM (#23338141)
The class will have to provide you with an option to get your answer back after a computation, so that's what you test. I don't see a reason to test how a class computes a result as long as the result is correct.
Re:The use of `class` for things that should be simple free ... by nightski on Thursday May 28, 2020 @11:18AM (#23338339)
Well either you have internal state or you don't. If you don't have internal state (and it just returns the answer), then there is no difference between it and a function.

If it does have internal state, then the answer it returns depends on the value of that internal state which means it's hard to verify that the answer returned is correct since you have to know the internal state of the object.

Re:The use of `class` for things that should be simple free ... by simiones on Thursday May 28, 2020 @11:36AM (#23338540)
The whole idea of internal state is that it is not accessible (so not relevant) to the outside world.

You test a class as a user by calling its methods in the desired order (per requirements and documentation) and you check that the results you get are correct. If the results are correct, the class fits your use case. If they are not, then you're either calling it wrong or it has a bug. Either way, no need to know the internal state.

Re:The use of `class` for things that should be simple free ... by bermanoid on Thursday May 28, 2020 @03:06PM (#23341081)
That's a great ideal, and I understand the arguments in favor, but the reality is that sometimes in order to test all of the internal code paths, you have to go to extremes when only interacting via the public interface. If I'd have to write 50 lines of extra testing code (or worse, extend various classes to add fake hooks into external dependencies, etc., which is where testing tends to really get messy) to validate that some edge case is handled appropriately, it's sometimes worth skipping that and fiddling some internal state to jump straight to the edge case.
Re:The use of `class` for things that should be simple free ... by nightski on Thursday May 28, 2020 @11:41AM (#23338594)
"Calling its methods in the desired order"

This is my point. The order of calling the methods matters, because it manipulates opaque internal state. Since this ordering matters, the caller is implicitly dependent on this internal state as it must know the order to call the methods in to get the desired result.

So it's very relevant to the outside world in my opinion and nothing is truly hidden. It becomes part of the public API whether you hide it or not.

Re:The use of `class` for things that should be simple free ... by simiones on Thursday May 28, 2020 @12:48PM (#23339470)
It still depends.

Think of a List class. Let's say it has methods to add, remove and retrieve elements, and it has a method to retrieve the size.

Let's say the internal implementation is an array with a fill pointer.

Obviously, before you can usefully call list.get(7), you must have called list.add(T) at least 7 times (assuming no deletes).

Do you need to know the the state of the backing array and the value of the fill pointer? Do you need to know whether there even is a fill pointer, or a linked list underneath (obviously, the performance would be different so you would need to know at some point)?

Re:The use of `class` for things that should be simple free ... by jayd16 on Thursday May 28, 2020 @02:48PM (#23340883)
You do not want to test private implementation. You should be testing the public contract only. Reaching in and making private things public crystallizes the implementation and reduces your ability to refactor.
Re:The use of `class` for things that should be simple free ... by kortilla on Thursday May 28, 2020 @12:41PM (#23339380)
If you’re asserting non-public internals of a class, your testing is wrong in the first place. Assert outcomes, not the process.
Re:The use of `class` for things that should be simple free ... by nightski on Friday May 29, 2020 @11:52AM (#23351450)
That's the whole point. You can't test outcomes if they are dependent on internal hidden state as that affects the outcome.

Whether you make it private or not hidden state leaks into the output since the output is dependent on it.

Re:The use of `class` for things that should be simple free ... by kortilla on Sunday May 31, 2020 @03:00PM (#23371739)
It sounds like you’re confusing side effect free code with OOP. You can use OOP while having side effect free stuff that never requires you to assert internals.
Re:The use of `class` for things that should be simple free ... by cma on Thursday May 28, 2020 @11:43AM (#23338613)

    Tests.h
    #define private public
    #define protected public
Re:The use of `class` for things that should be simple free ... by rashkov on Thursday May 28, 2020 @10:58AM (#23338037)
Maybe I'm mis-reading it, but it seems that your comment is just a re-statement of what your parent comment is replying to. It’s like, “Why A” “Because B” “But why A?”
Re:The use of `class` for things that should be simple free ... by crimsonalucard1 on Thursday May 28, 2020 @12:20PM (#23339083)
Because it's like using a while loop to print out each character in a string when you can just do print to print the entire string.

I don't want to worry about external methods modifying state, I don't want to deal with constructors, I don't want to deal with instantiating state or modifying state before I call my function.

My function just takes a state and returns a new state. Simple.

Re:The use of `class` for things that should be simple free ... by ImprobableTruth on Thursday May 28, 2020 @10:58AM (#23338048)
In what way do you 'need' a class? It uses none of the features that a class provides over normal structs.
Re:The use of `class` for things that should be simple free ... by simiones on Thursday May 28, 2020 @11:43AM (#23338608)
The idea is, if you need the functionality that classes give you (passing the implicit state between multiple calls), why not use the special syntax for that use case?
Re:The use of `class` for things that should be simple free ... by dkersten on Thursday May 28, 2020 @02:12PM (#23340440)
Because sometimes you don't need a class, or don't need the full-blown machinery that an object system entails.
Re:The use of `class` for things that should be simple free ... by simiones on Thursday May 28, 2020 @11:34AM (#23338498)
Objects with a single public method are more tedious than equivalent closures. Objects with multiple public methods are much more friendly than closures with multiple public entry points (they can be done, but they look and feel hacky).

Also, pieces of data that hide their internal structure and just expose an API to modify that data (Objects) are a very useful construct, and used in all languages with first-class mutation. Some languages have special syntax for this case (e.g. C++, Python, Go, OCaml), some don't (e.g. C). For example, no language that I know of exposes a mutable List type with a public count of elements. Neither does any language I know of expose a mutable List type as a closure.

Re:The use of `class` for things that should be simple free ... by optimiz3 on Thursday May 28, 2020 @11:18AM (#23338343)
> Passing around state via variables is no more tedious

But it is - the programming language is now repeatedly quizzing you on something you've already told it.

Re:The use of `class` for things that should be simple free ... by crimsonalucard1 on Thursday May 28, 2020 @12:18PM (#23339056)
Well I mean would you rather have this:

    method(state){
        return doSomething(state)
    }
Or this:

   class A:
       otherThingThatMutatesState1()
       otherThingThatMutatesState2()
       otherThingThatMutatesState3()

       method(){
          this.state += 1 // or some other mutation
       }
Re:The use of `class` for things that should be simple free ... by panopticon on Thursday May 28, 2020 @12:06PM (#23338898)
That depends on the language. Haskell provides some nice syntax here with monads.
Re:The use of `class` for things that should be simple free ... by robocat on Thursday May 28, 2020 @03:36PM (#23341557)
> There is nothing that you can do with an object that you can’t do with a closure

How do you prevent memory “leaks” due to the banana referencing a forest problem? With JavaScript libraries returning a function pointer, the returned function pointer would often have a closure that contained a lot of irrelevant state. There is no easy way to reason about the leak, there is virtually no way to work out the cause at runtime (debuggers can help, but a problem with increasing memory usage certainly is not easy to diagnose why). Even when really conscientious about the problem, it is seriously hard to avoid the problem or inadvertently create a closure e.g. many programmers are unaware that arguments may not get GCed if you add an event handler within a function (closing over arguments and maybe other variables).

Objects have their problems, but the memory leak problem with JavaScript closures is insidious and very very hard to fix.

Re:The use of `class` for things that should be simple free ... by epidemian on Thursday May 28, 2020 @11:35AM (#23338519)
Though i agree with with your general statement, i think the 1/10th the size figure is a bit disingenuous. At least the cases where i've gone from the unnecessary OO style to a simpler function/procedure based solution (in JS, which supports both styles just nice), the code size difference hasn't been anything that great. At most it's been half the size. Which is a lot i think! But not an order of magnitude less.

I'm noting this because i think that number kinda detracts from your main argument, with which i agree completely. I think even if the code would remain roughly the same size, the removal of OO would still be worth it, since, as you mention, is much less jargon and conceptual baggage. And if i can achieve the same result with a much simpler conceptual model and language, then all the better :)

Re:The use of `class` for things that should be simple free ... by amw-zero on Thursday May 28, 2020 @11:41AM (#23338599)
I will definitely admit that those numbers are made up, more of a rhetorical technique. Numbers are important, I do agree.
Re:The use of `class` for things that should be simple free ... by fendy3002 on Thursday May 28, 2020 @12:05PM (#23338890)
For JS, it's best to avoid class as possible, due to this and bind / apply shenanigans.

Closure and function return function can be used as substitute, and except for inheritance (which should be avoided too), I haven't found any use case for using class class. Example:

    function MyList {
      let data = [];
      let add = (item) => data.push(item);
      return { add };
    }
Re:The use of `class` for things that should be simple free ... by nonsense1234 on Thursday May 28, 2020 @12:47PM (#23339452)
> Closure and function return function can be used as substitute

So for every list you have an additional allocation for the add function. It obviously continuously to get much worse as more "methods" are inevitably added. That's extremely inefficient for something that's used often and it's not something JavaScript engines can optimize away. The benefit is also extremely negligible since the closed over values are still implicit in the call to add.

Re:The use of `class` for things that should be simple free ... by dingoegret on Thursday May 28, 2020 @03:25PM (#23341348)
Exactly. So you aren't proposing any improvements if by your own admission, it's no more tedious.

Except that it's actually more tedious implementing your own bootleg object. Then managing the scope, namespace and pointers. When they could all be contained inside a language construct guaranteed to follow the rules.

Re:The use of `class` for things that should be simple free ... by crimsonalucard1 on Thursday May 28, 2020 @12:14PM (#23339010)
Less complexity to deal with. No need to worry about external scope or external methods mutating properties on objects. No need to think about constructors or anything else. No need to worry about inherited properties. No need to instantiate the object before executing the method.

All you need to do is define a function and call it.

Literally, again I urge you to take a look at the following example, it's waay more simple than OOP:

https://news.ycombinator.com/item?id=23338700

Re:The use of `class` for things that should be simple free ... by sly010 on Thursday May 28, 2020 @12:00PM (#23338811)
But you _are_ passing `this` around with OO code too. It just ends up being before the dot (or arrow), instead of being an argument. All you did is loose some flexibility.

OO couples behavior with state. Sometimes that's exactly what you want (e.g. containers). And sometimes you just need data, functions and namespaces and all 3 are available in C++ outside classes.

Re:The use of `class` for things that should be simple free ... by mattkrause on Thursday May 28, 2020 @07:11PM (#23344164)
But I don't want that flexibility!

If my state has some invariant, I want to be sure that I can trust it. I don't want to worry that someone will mess with it, breaking the invariant, or accidentally pass in stale state.

If that's all handled automagically by the object, it's out of sight, out of mind. Add in a get_state() and set_state() method if you need it as an escape hatch or for testing.

Re:The use of `class` for things that should be simple free ... by JoeAltmaier on Thursday May 28, 2020 @05:21PM (#23342821)
Ok mostly true. It can also be part of a function pointer.
Re:The use of `class` for things that should be simple free ... by yawboakye on Thursday May 28, 2020 @10:23AM (#23337607)
You lost me at “there’s a lot of object-hating going around.” Conversely there’s a return to being mindful of how we use the computer’s resources. Lately I’ve been reading about Ruby internals, and rather than be impressed I’m terrified by how staples such as classes are implemented.
Re:The use of `class` for things that should be simple free ... by dingoegret on Thursday May 28, 2020 @03:35PM (#23341536)
Objects do not necessarily mean polymorphism and they certainly don't necessarily mean polymorphism via dynamic dispatch. For example, it's entirely possible to just use objects all within the stack. It's entirely possible to implement monomorphism via generics.

So yes, object-hate characterises the popular but tiresome anti OOP sentiments going around.

Re:The use of `class` for things that should be simple free ... by tempodox on Thursday May 28, 2020 @08:39AM (#23336541)
What you call “for free”, I call implicit. Passing it as function arguments makes it explicit. You don't need to “hate” “objects” to prefer the explicit over the implicit.
Re:The use of `class` for things that should be simple free ... by nitrogen on Thursday May 28, 2020 @09:51AM (#23337204)
I don't find all that much of a difference between notations like set.map{...} and map(set){...}, so at that point I suppose it really is just aesthetic preference.
Re:The use of `class` for things that should be simple free ... by totony on Thursday May 28, 2020 @10:03AM (#23337321)
Classes usually have a more complex state than the state passed to utility functions, which is a reason I'd be incline to use e.g. a struct as a state vs a C++ class. Makes it harder to write bad code.
Re:The use of `class` for things that should be simple free ... by kyralis on Thursday May 28, 2020 @12:12PM (#23338979)
So, let's say what you actually mean here: overly complex state is a problem, regardless of the syntactic sugar around passing it.

I've seen monstrous state variables passed around to "pure functions" at least as much as I've seen monstrous god objects; the problem is around complexity and data flow design and has very little to do with function vs object.

Re:The use of `class` for things that should be simple free ... by totony on Thursday May 28, 2020 @05:50PM (#23343180)
Yes that's my thinking. Everything can be done both ways, but in my experience structs have a better track record. Also different languages implement objects differently which adds mental overhead. Copying structs or marking them read-only is also usually easier vs an object which manipulates its own state.
Re:The use of `class` for things that should be simple free ... by Tomis02 on Friday May 29, 2020 @03:14AM (#23347106)
Upvote for the comment, but the reality is OOP (at least in C++) encourages people to write code this way. When you have a sufficiently large code base and an unforeseen requirement comes in, one that wasn't planned for in those architectural committees, you have a problem. And that problem is solved by either a man-century of refactoring, or by taking some shortcuts that destroy the purity of the code and eventually lead to these monstrous god objects that you mentioned. This happens over and over, to the point where you can't just say "oh it was an accident, happened just one time".
Re:The use of `class` for things that should be simple free ... by samatman on Thursday May 28, 2020 @11:21AM (#23338379)
Sounds like you would enjoy Uniform Function Call Syntax!

https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax

Re:The use of `class` for things that should be simple free ... by quietbritishjim on Thursday May 28, 2020 @09:07AM (#23336780)
I think you could apply your argument to any use of objects, unless there are virtual methods involved. So you probably would have to be pretty generally against the use of objects to agree.
Re:The use of `class` for things that should be simple free ... by tempodox on Saturday May 30, 2020 @08:20AM (#23360642)
Classes for use with stack-allocated instances in C++ are also very handy. Makes it easy to control the extent (i.e. lifetime) of the side-effects they produce.
Re:The use of `class` for things that should be simple free ... by JoeAltmaier on Thursday May 28, 2020 @08:53AM (#23336638)
Except for the title of the OP, which seems argumentative.

The context pointer for an encapsulated set of functionality, need not be passed around. It adds little or nothing. In a language full of encapsulated functionality, it stands out like Chekov's Gun. I'd argue, there better be a damn good reason to deviate for normal practice. And not just 'I prefer the explicit'.

Re:The use of `class` for things that should be simple free ... by nwmcsween on Thursday May 28, 2020 @11:49AM (#23338694)
There isn't object hating it's just writing the simplest program that does what you need, having n layers of indirection requires the programmer to keep context of n layers. If you need the indirection create it when you need it.
Re:The use of `class` for things that should be simple free ... by Tomis02 on Friday May 29, 2020 @02:56AM (#23346991)
> Use objects to encapsulate functionality

Sadly objects are also used in an attempt to hide data (because direct access to data is considered dirty in OOP).

Now, consider a non-trivial OOP class hierarchy. You have an object that needs to mutate another object's data (an object that is completely unrelated to your initial object). In order to solve this you have options:

- completely rearchitect your code so that you take this use case into account

- find the shortest path between these two classes and add setters to each class

- hack the code and call it "technical debt"

First one is not feasible, second one is unmanageable (complexity increases dramatically), third one is usually chosen.

Speaking from experience, OOP is most of the time the worst tool for the job.

Re:The use of `class` for things that should be simple free ... by JoeAltmaier on Friday May 29, 2020 @08:59AM (#23349383)
OR, don't use a 'setter', use a carefully named API that describes the purpose instead. Or design the two classes to share the data with locks. Or whatever your solution requires.

Yes breaking encapsulation willy-nilly is a bad thing. So don't.

I don't doubt there are bad programmers out there. Blaming the hammer for a bad carpenter is foolishness.

Btw objects are used for like 5 different things. Choose what works for your problem space.

Re:The use of `class` for things that should be simple free ... by Tomis02 on Friday May 29, 2020 @09:22PM (#23357590)
> don't use a 'setter', use a carefully named API that describes the purpose instead.

Call it whatever you want, the requirement is for one class to produce a side effect in a completely unrelated part of the code (happens all the time). This doesn't fit with the current architecture, and there was no way of predicting it beforehand. Now what? Rewrite everything? What happens if you're in a department of 30 developers? Tell them "hold on while I go back to the drawing board to create a clean design"?

OOP isn't a hammer, it's duct tape, and carpenters are taught from school that duct tape is the main way of doing carpentry. It's duct tape because it ties data to functions in a way that makes it very difficult to extract or reuse that data somewhere else.

When OOP is your religion you don't blame the bad carpenters, you blame the master priest.

Re:The use of `class` for things that should be simple free ... by crimsonalucard1 on Thursday May 28, 2020 @12:10PM (#23338953)
I would argue that it is actually waaay more awkward to use objects for this. See my example code here:

https://news.ycombinator.com/item?id=23338700

You will see that it is far more concise and intuitive to do it with a function.

Re:The use of `class` for things that should be simple free ... by cataphract on Thursday May 28, 2020 @03:53AM (#23334642)
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.
Re:The use of `class` for things that should be simple free ... by kqr on Thursday May 28, 2020 @04:34AM (#23334905)
There's one big difference in terms of convenience in many common implementations of classes and methods. There are essentially three different pieces involved:

In OO notation, we have A.B(C)

In almost all languages, you can store C in a variable and supply it "later":

    z = C
    A.B(z)
You can also store A in a variable and supply it "later":

    x = A
    x.B(C)
However, it is much more rare to be able to store B in a variable and supply it "later". Often, you must store A.B:

    xy = A.B
    xy(C)
This means that at the time you select which method to call, you must also have at your disposal the instance on which you want to call it!

With functions, things get easier. If you have B(A, C), you can generally just store B in a variable on its own:

    y = B
    y(A, C)
Some OO languages allow you to store plain methods that aren't yet bound to a particular instance (JavaScript, modern Java) but far from all do, without resorting to inconveniences like

    y = lambda o: o.B
Please note that what this workaround accomplishes is effectively to turn the method into a function!

I suspect the main argument here is that it just doesn't make sense notationally to treat the first argument to a function specially. It only introduces wierd edge cases that have to be worked around. Plain old function notation has stood the test of time for good reason: it's flexible and handles most of the common cases we want.

Re:The use of `class` for things that should be simple free ... by Huperniketes on Thursday May 28, 2020 @08:37AM (#23336531)
>There's one big difference in terms of convenience in many common implementations of classes and methods.

Which ones?

>However, it is much more rare to be able to store B in a variable and supply it "later". Often, you must store A.B:

How is it rare? Smalltalk doesn't require you to specify the receiver when storing a symbol. Neither does Objective-C (selector). Neither does Ruby. Nor Java.

Which commonly used languages require one to have the receiver tied to the method when memoized? C++ is the only one I'm aware of. So it might be rare to do it in C++, but not in OOP generally.

Re:The use of `class` for things that should be simple free ... by frutiger on Thursday May 28, 2020 @08:55AM (#23336654)
Even C++ lets you store the address of the member function and lets you invoke it with an instance later.
Re:The use of `class` for things that should be simple free ... by Huperniketes on Thursday May 28, 2020 @08:59PM (#23345119)
> Even C++ lets you store the address of the member function and lets you invoke it with an instance later.

Not for virtual member functions (not that I've been able to find). C++ is geared towards generating optimal executables. Since the type of the object is known at compile-time, the particular function used for that type is known, and the compiler will generate code that applies for it.

This is why C++ uses mangled names: to discriminate between identically named functions of different types and signatures.

Re:The use of `class` for things that should be simple free ... by projektfu on Thursday May 28, 2020 @03:29PM (#23341416)
Java before invokedynamic, I guess.
Re:The use of `class` for things that should be simple free ... by vanderZwan on Thursday May 28, 2020 @06:52AM (#23335826)
I like the approach Wouter van Oortmerssen uses in Lobster:

    class Animal:
        alive = true

    class Cat : Animal
        def hello(): print "meow"

    class Dog : Animal
        barked = 0

    def hello(d::Dog):
        print "bark!"
        barked++

    let d = Dog {}
    d.hello()

    let a:Animal = d
    a.hello()
In other words, A.B(C) is just syntactic sugar for B(A, C), and class definitions are just syntactic on top of that. The relation between OO and regular functions and stateful objects is completely transparent (the only real gotcha I can see is that a.hello() still works here because it was assigned a subclass where this method is defined). This makes it easy to store B for later usage, like you wanted to do in your example, and reason about its behavior.

[0] http://strlen.com/lobster/

Re:The use of `class` for things that should be simple free ... by beagle3 on Thursday May 28, 2020 @07:25AM (#23336039)
This is also the approach taken by Nim and D, and it is known as the UFCS (Uniform Function Call Syntax)[0], and I agree - it's the best of all worlds.

[0] https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax

Re:The use of `class` for things that should be simple free ... by vanderZwan on Thursday May 28, 2020 @07:26AM (#23336047)
Ah, I wondered where it originated. Thank you for that bit of info!
Re:The use of `class` for things that should be simple free ... by amw-zero on Thursday May 28, 2020 @09:15AM (#23336843)
I think Swift does this too?
Re:The use of `class` for things that should be simple free ... by edflsafoiewq on Thursday May 28, 2020 @04:47AM (#23334977)
> This means that at the time you select which method to call, you must also have at your disposal the instance on which you want to call it!

That is also its advantage, since the method to call can depend on the instance. Not just for dynamic dispatch either. A statically dispatched call will look up B on classof(A).

Re:The use of `class` for things that should be simple free ... by DarkWiiPlayer on Thursday May 28, 2020 @04:43AM (#23334950)
I'd just like to add that you can still have the `A.B(C)` syntax, if you just define it as syntactic sugar for `(class of A).B(A, C)`
Re:The use of `class` for things that should be simple free ... by Tomis02 on Friday May 29, 2020 @03:28AM (#23347178)
> This means that at the time you select which method to call, you must also have at your disposal the instance on which you want to call it!

The time you "select which method to call" is when you write the code, right? You select it once. Like, "printf(arg);". I selected printf (in my mind), I called it. I don't need to do "x = print; x(arg)".

> With functions, things get easier. If you have B(A, C), you can generally just store B in a variable on its own:

> y = B

> y(A, C)

>Some OO languages allow you to store plain methods that aren't yet bound to a particular instance (JavaScript, modern Java) but far from all do...

Sorry, I lost the plot here. If you have B(A, C) then you don't need "y = B". B is an invariant of sorts. Just like you don't usually store the address of a class method; you just call that method on an object. Nobody writes:

> x = &objectInstance::method;

> x(args);

People just write

> "objectInstance.method(args);"

Therefore in your case, if using functions, you just do B(A, C). No assignment needed, works in every language.

What am I missing?

Re:The use of `class` for things that should be simple free ... by logicchains on Thursday May 28, 2020 @07:55AM (#23336221)
>But if you're passing a state object around, you might as well use a class, no?

A lot of your functions aren't going to need access to the whole state, only to some of it. If we're not using a class, we can just make these functions take only the needed arguments, rather than the whole state. This makes them easier to reason about, as we can know from the function signature that it only looks at the params we pass in, not the whole state. It also makes them easier to reuse elsewhere in the code, where we might not have the full state but we do have the arguments to the function.

For any function that doesn't need to access every member variable of a class, making it a class member function essentially creates an unnecessary coupling between that function and the class members variables it doesn't use. This makes it unecessarily harder to reuse elsewhere, as anyone who wants to use it needs to create an instance of the whole class, including any variables that aren't needed by that function.

Re:The use of `class` for things that should be simple free ... by lmkg on Thursday May 28, 2020 @11:19AM (#23338359)
This sounds like exposing internal implementation details. You're pushing some complexity onto the caller, and breaking up the uniformity of the interface. Sometimes the caller will want to manage that complexity for the reasons that you describe, but it's not always good to force the caller to wrangle that complexity.

Design trade-offs, as always. I get why you would do it your way, and it makes sense in some applications. But for some applications the fact that you're hiding which specific bits of state each function depends on, is actually the point of using a class.

Re:The use of `class` for things that should be simple free ... by fnord123 on Thursday May 28, 2020 @05:05AM (#23335078)
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 ... by jcelerier on Thursday May 28, 2020 @06:07AM (#23335532)
> 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.

definitely not all, only things that change the layout. adding a non-virtual method does not break ABI at all for instance.

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

Does this have a point in 2020 ? Good modern practice (c.f. Rust, etc) is to ship LTO'ed mostly-static binaries. Such hiding is only relevant for legacy things such as what Linux distros obstinates themselves in doing for their userspace - hopefully in a few years everyone will switch to snap / flatpack / appimage to finally reach a sane application distribution model on Linux.

I'd definitely say PIMPL is 100% an anti-pattern in every possible case. It forces more memory allocations, and makes it much harder to hack your way out of things when it's 3AM and everything is crashing and you have 5 minutes to fix things before heads start to roll.

Re:The use of `class` for things that should be simple free ... by fnord123 on Thursday May 28, 2020 @06:43AM (#23335768)
> only things that change the layout. adding a non-virtual method does not break ABI at all for instance.

Yes, you are correct. The point was that C code can keep the ABI intact through (some) data layout changes but vanilla C++ classes cannot I misstated it.

>Good modern practice (c.f. Rust, etc) is to ship LTO'ed mostly-static binaries.

That is the state of play now because Rust does not have a stable ABI. I thought one might be coming but maybe no one's working on it. It's unfortunate because it would be really nice to have binary crates with signing.

>hopefully in a few years everyone will switch to snap / flatpack / appimage to finally reach a sane application distribution model on Linux.

Snap has a while to go before it can be adopted fully. Images are enormous, they take a long time to load, and they don't respect (or don't understand) hidpi settings. I tried to use it for spotify and telegram-desktop and other applications but they just don't work that well.

>it much harder to hack your way out of things when it's 3AM and everything is crashing and you have 5 minutes to fix things before heads start to roll.

Absolutely but it comes from enormous systems like Windows where changing a library and breaking ABI means recompiling Everything. And these compilation jobs are often 'overnights'.

Re:The use of `class` for things that should be simple free ... by MaulingMonkey on Thursday May 28, 2020 @06:40PM (#23343812)
> adding a non-virtual method does not break ABI at all for instance.

Ctors/dtors can break ABI as well: https://gcc.godbolt.org/z/XAx00v

Re:The use of `class` for things that should be simple free ... by asveikau on Thursday May 28, 2020 @10:28AM (#23337680)
> Does this have a point in 2020 ? Good modern practice (c.f. Rust, etc) is to ship LTO'ed mostly-static binaries.

It sure sounds to me like modern practice as you've defined it is that when a component has a security vulnerability you're not going to patch it. It's going to be statically linked and running in a container image maybe created by somebody else and you'll have no idea it's there.

Re:The use of `class` for things that should be simple free ... by MaulingMonkey on Thursday May 28, 2020 @05:06PM (#23342622)
Dynamic linking is no panacea here.

Yes, it theoretically lets you ship a patch version bump containing security fixes for the few languages with a stable ABI. But even ignoring the deluge of unpatched IOT garbage running seriously out of date kernels - nevermind userspaces - how do you ship that version bump of your library to your Windows users? Your OS X users? iOS? FreeBSD? RedHat? Android? Mint? Debian? PS4? Redox? Xbox One? Solaris? Switch? I've dynamically linked into PuTTY before - a good 'ole C codebase - and I still had to rebuild and redeploy myself when a security patch landed.

Meanwhile, an updated package on crates.io can change deps.rs badges, or trigger dependabot - optionally auto-merging the pull request if CI passes, or altering you to the build failure and need for manual action if that "patch" version broke things. Rustsec and cargo audit/geiger/crev are all hideously platform independent ways to catch problems. My patches to an unsound Rust crate can automatically land on your WASM-enabled website if you have things so configured.

Re:The use of `class` for things that should be simple free ... by pas on Thursday May 28, 2020 @07:01AM (#23335882)
I'd like to see the NixOS approach merged with flatpak/snap/whatever. Basically secure/deterministic, fine grained dependencies. Yet easily shared (since they are just content-addressable), and easily updated (since you don't actually have to depend on the content-hash, and distro maintainers can still coalesce the versions of many-many packages' common dependencies).
Re:The use of `class` for things that should be simple free ... by jfkebwjsbx on Thursday May 28, 2020 @07:19AM (#23335998)
> Good modern practice (c.f. Rust, etc) is to ship LTO'ed mostly-static binaries.

What Go and Rust do (by default) is only useful for internal software that you have full control of (both in source and in updates), but it is definitely not "good practice" for general software distribution.

Going fully static (Go) or mostly static (Rust) means your users/clients cannot update dependencies easily. Users will suffer when the vendor is not replying as quickly as they would hope for (which is not a pleasant experience at all, specially if you run server software) or when they simply discontinue the software (cf thousands of games). Then there is the usual duplicated code pages with less effective cache utilization etc. (which is a minor issue nowadays but if everything is a 100 Mo Electron copy it starts being painful).

Re:The use of `class` for things that should be simple free ... by loopz on Thursday May 28, 2020 @07:51AM (#23336198)
Users/clients could expect to be able to upgrade minor OS/utility versions, but not direct dependencies. There's no reason to expect rogue upgrades of dependencies to work out of the box, unless explicitly guaranteed by subvendors ie. within minor versions. The modern approach is to encapsulate the complexity within a static binary, or even containers with more files. The deliverables are provided and guaranteed by the vendor. If there are security issues, 99% of that should rather be solved by safe language usage and security perimeter or encrypted channels, while refraining from unsafe library dependencies and direct connections to core business processes.

Linux packaging is interesting, since the delivery model of gratis distributions often have no such guarantees. Thus one may indeed experience difficulties at any moment after a recent upgrade due to that model. In that case, the complexity lies within upstream and distro, a shared responsibility that the distro should reconcile but may fail to do in minute detail.

Modern methods involve a pipeline, and no rogue upgrades that haven't passed multiple stages of tests and security checks.

Re:The use of `class` for things that should be simple free ... by jfkebwjsbx on Thursday May 28, 2020 @05:10PM (#23342686)
> There's no reason to expect rogue upgrades of dependencies to work out of the box

If they don’t work, they are broken. Of course it can happen, but the opposite approach means never being able to do it.

> If there are security issues, 99% of that should rather be solved by safe language usage and security perimeter or encrypted channels

There is no mainstream language or operating system out there that solves "99% of security issues" unless you are talking about formally proven systems etc.

> The deliverables are provided and guaranteed by the vendor.

As I explained in the GP, this only happens for systems with support contracts.

For most software out there, this isn’t the case. Mainstream software vendors don’t guarantee you anything at all, for good reasons.

> Modern methods involve a pipeline, and no rogue upgrades that haven't passed multiple stages of tests and security checks.

That is not "modern". That is how it has always been done since the 80’s. Again, for software properly supported.

I am not sure why you talk about "rogue" updates, since nobody has mentioned such.

Re:The use of `class` for things that should be simple free ... by jcelerier on Thursday May 28, 2020 @07:58AM (#23336237)
> Users will suffer when the vendor is not replying as quickly as they would hope for (which is not a pleasant experience at all, specially if you run server software) or when they simply discontinue the software (cf thousands of games).

My experience as a Linux user is that I suffer even more from some minor update in /usr/lib/libwhatever.so suddenly breaking some feature in software that I use to do my job / have fun, which wouldn't happen at all if that software was self-contained.

Re:The use of `class` for things that should be simple free ... by jfkebwjsbx on Thursday May 28, 2020 @05:17PM (#23342776)
Being self-contained does not imply statically linked, though.

The benefit of dynamically linking is that you (as a user) or upstream (most likely) can fix those issues you point out, including future ones.

Being self-contained simply means updates aren’t forced into it, which is a good thing and I agree with it.

I didn’t downvote you, by the way, since the point you make is valid.

Re:The use of `class` for things that should be simple free ... by nicoburns on Thursday May 28, 2020 @05:32AM (#23335248)
> 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 ... by fnord123 on Thursday May 28, 2020 @05:54AM (#23335450)
Java has the possibility of maintaining ABIs as well. And I imagine that's what .Net assembles are about too.

I think you're heavily over stating reliance on libraries having stable ABIs as an anti-pattern. If a mistake is made in the ABI promise, can it get hairy? Absolutely. If you work on an application and are somewhere in the middle of it and need to recompile it to test a fix, do you want to wait for the compilation of the entire application to test it? Obviously not.

Re:The use of `class` for things that should be simple free ... by im3w1l on Thursday May 28, 2020 @09:11AM (#23336818)
In C you would do

    my_lib_cool_func(myobj, 1, 2, 3);
so you don't pollute the global namespace excessively. Having it accessed through the object avoids that.
Re:The use of `class` for things that should be simple free ... by Const-me on Thursday May 28, 2020 @06:43AM (#23335775)
> Is this better?

Very few professional developers code in vim or notepad. Vast majority of us are using IDEs. IDE knows types of things, type `myobj.` and you'll get a suggestion list with methods of that class callable from the current context.

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

There's another useful pattern in C++:

    struct iObj
    {
        virtual ~iObj() { }
        virtual void cool_func( int a, int b, int c ) = 0;
        static std::unique_ptr<iObj> factory();
    };
Re:The use of `class` for things that should be simple free ... by mrep on Thursday May 28, 2020 @07:24AM (#23336028)
> Very few professional developers code in vim or notepad

Notepad++ and vim are the 3rd and 5th most popular development environment according to stack overflows 2019 report [0] and I and many others I know use Vim at least.

> IDE knows types of things, type `myobj.` and you'll get a suggestion list with methods of that class callable from the current context.

I've never used notepad but Vim absolutely supports omni completion [1].

[0]: https://insights.stackoverflow.com/survey/2019

[1]: https://vim.fandom.com/wiki/Omni_completion

Re:The use of `class` for things that should be simple free ... by jcelerier on Thursday May 28, 2020 @08:33AM (#23336483)
> Notepad++ and vim are the 3rd and 5th most popular development environment according to stack overflows 2019 report [0] and I and many others I know use Vim at least.

in C++ the ratio of ppl I know using an IDE with semantic code completion ability (that is, not rtags but actually using e.g. libclang or something that does understand C++ to some extent for IDE completion) vs "glorified text editors" must be 95/100 using an IDE though.

Re:The use of `class` for things that should be simple free ... by fnord123 on Thursday May 28, 2020 @10:07AM (#23337365)
Vim and VS Code have access to semantic code completion through the language server protocol.

But your assertion is weird. Either you work on Windows where everyone is on Visual Studio, or you have 95/100 people around you using CLion, XCode, and Qt Creator, two of which don't even have an entry on GP's survey link. One of which is probably only used to sign apps for ios. Could you give more info?

Re:The use of `class` for things that should be simple free ... by gpderetta on Thursday May 28, 2020 @10:30AM (#23337708)
I use emacs with clangd on a fairly large (~2M lines of code), but between clangd getting stuck, crashing or being too slow, I don't really get much benefits from it. When it works is great though.

TBH, in my limited experience, I have never seen code completion working well on large C++ code bases. I remember years ago VS literally becoming unresponsive when intellisense was enabled.

Re:The use of `class` for things that should be simple free ... by fnord123 on Thursday May 28, 2020 @06:51AM (#23335820)
https://www.cairographics.org/manual/cairo-cairo-t.html

All operations on `cairo_t` have prefix `cairo_`

Re:The use of `class` for things that should be simple free ... by Const-me on Thursday May 28, 2020 @07:08AM (#23335918)
That's doesn't give context for IDE. You can type `cairo_` and get suggestions what may follow, but you can't type `x.` and get suggestions on what you can do with x.
Re:The use of `class` for things that should be simple free ... by eternauta3k on Thursday May 28, 2020 @12:14PM (#23339002)
While PIMPL has additional indirection for accessing member variables, this pattern has indirection for accesing methods (need to go through vtable).
Re:The use of `class` for things that should be simple free ... by fluffything on Thursday May 28, 2020 @06:43AM (#23335769)
Why? The main advantage of passing a state as an argument is letting the user control the state. If you need an array as state, the user might want to put the array on the stack, or the heap, or in static memory, or protected behind a mutex somewhere...

It doesn't really matter that much how things are actually implemented: most languages are flexible enough that you can do this with a class or a function or even implement the algorithm as a generic interface. But if you want the algorithm implementation to be reusable, you have to remove as many assumptions about the state as possible because otherwise some users won't be able to use your algorithm.

If you pick up a class, and the class owns the state, now you need to make the class generic to allow the user to customize the state, you need to allow the user to break the state invariants, to be able to unsafely read and write from it, because otherwise you are forcing the user to read into a separate buffer, and then make a copy to your class, etc.

Somebody that knows how to avoid all these issues when writing their algorithm as a class, probably also knows that by just using a function most of these issues just cannot happen anymore (or are much harder to introduce).

You can also write the algorithm as a function, that takes some generic state, and provide a "class wrapper" for convenience, so that those who don't want to customize anything don't have to. But then your class doesn't implement the algorithm anymore, it just wraps it.

Re:The use of `class` for things that should be simple free ... by jmull on Thursday May 28, 2020 @07:34AM (#23336090)
If we’re talking about an algorithm as a class, the state managed by the class is algorithm state, not the data the algorithm acts on. The data the algorithm acts on should probably be passed as a parameter regardless of whether the algorithm is implemented as a class or top-level function.
Re:The use of `class` for things that should be simple free ... by fluffything on Thursday May 28, 2020 @09:52AM (#23337224)
> If we’re talking about an algorithm as a class, the state managed by the class is algorithm state, not the data the algorithm acts on.

I was only talking about algorithm state here. Check, for example, how the C++ string searching algorithms work to get a feeling of how these APIs work in the wild. For an example of this gone wrong, look no further than C++ stable_search, which does not let the user reuse the merge sort buffer across searches.

Re:The use of `class` for things that should be simple free ... by jmull on Thursday May 28, 2020 @01:15PM (#23339838)
Hm, I guess this is moving in the direction of a debate on semantics and API design... which is independent of the original topic.

I don’t know what stable_search is, but it would be a design decision if/how it supports different memory management options for buffers, and isn’t really affected by the decision to use a class or top-level function for implementation. Either way, buffer allocation could be hidden in the implementation and out of the user’s control or exposed to some degree and under the user’s control.

Re:The use of `class` for things that should be simple free ... by amw-zero on Thursday May 28, 2020 @03:58AM (#23334675)
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.
Re:The use of `class` for things that should be simple free ... by jabirali on Thursday May 28, 2020 @04:20AM (#23334835)
In many languages, it is an explicit parameter though.

For instance, in Python, one would define a function with `def fun(state)` or a class method with `def fun(self)`. In the function body, one would use respectively `state.var` or `self.var` to refer to a variable `var` in the state object. Running it is then done using `fun(state)` or `state.fun()`.

There are some minor syntactic differences between the two, but I find both these examples to be just as explicit...

Re:The use of `class` for things that should be simple free ... by mcv on Thursday May 28, 2020 @05:19AM (#23335153)
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 ... by still_grokking on Thursday May 28, 2020 @04:43AM (#23334946)
So you would not use type-classes in Haskell as they rely on implicitly passed parameters to functions?
Re:The use of `class` for things that should be simple free ... by kqr on Thursday May 28, 2020 @04:50AM (#23334988)
I can't speak for the GP, but what makes typeclasses in Haskell work for me is that there's a very strong cultural force ensuring that they are truly about consistency boundaries and maintaining invariants/laws.

Haskell developers don't just create a typeclass to bunch related functionality together. Doing so is a common beginner's anti-pattern. Typeclasses exist to wrap up general operations that satisfy some laws.

When objects in OOP are used in the same way, I don't mind it as much. It's when they're not that I don't find the syntactic inconvenience worth it.

Re:The use of `class` for things that should be simple free ... by js8 on Thursday May 28, 2020 @05:57AM (#23335473)
In Haskell typeclasses, it's the type of the parameter that is implicitly passed, not the parameter itself.
Re:The use of `class` for things that should be simple free ... by uryga on Thursday May 28, 2020 @06:09AM (#23335546)
i don't think that's correct, afaik typeclasses roughly desugar to passing a record of functions (vtable/"dictionary") at the call site
Re:The use of `class` for things that should be simple free ... by taejo on Thursday May 28, 2020 @06:31AM (#23335684)
And that vtable depends on the type, not the value.
Re:The use of `class` for things that should be simple free ... by uryga on Thursday May 28, 2020 @12:36PM (#23339301)
i guess there's really two implicit arguments - the value's type, `a` (quantified via forall - the System F "Λ") and its vtable `Show a`... though i guess the vtable is uniquely determined by the type bc in Haskell instances are globally unique
Re:The use of `class` for things that should be simple free ... by fauigerzigerk on Thursday May 28, 2020 @04:14AM (#23334807)
The canonical answer is encapsulation. But in my view it's rarely a good idea to couple state related to an algorithm's invocation (e.g a cache) with the data structure itself.
Re:The use of `class` for things that should be simple free ... by noobermin on Thursday May 28, 2020 @04:47AM (#23334974)
It's almost as if a hard and fast rule doesn't work, ie., the point of the article.
Re:The use of `class` for things that should be simple free ... by hamandcheese on Thursday May 28, 2020 @04:14AM (#23334801)
The benefit is encapsulation.
Re:The use of `class` for things that should be simple free ... by _0ffh on Thursday May 28, 2020 @04:59AM (#23335039)
Don't need a dedicated OOP lang for that benefit.

It's an age-old discussion. As old school software engineering became sufficiently advanced, some people bundled their favorite "state of the art" concepts, and called it OOP. (Also: Multiple people, multiple different concepts of what "OOP" actually precisely means.) It became a horrible hype, and from then on out everyone was taught to see all these concepts as "OOP concepts" that elevate OOP over other programming paradigms.

But they're not and they don't.

The only real "advantage" is, OOP languages are opinionated and will try to force their interpretation of these concepts on the coder. Which is nice, if you happen to like it that way. Just not everybody does.

Re:The use of `class` for things that should be simple free ... by fnord123 on Thursday May 28, 2020 @05:18AM (#23335149)
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 ... by thom on Thursday May 28, 2020 @07:06AM (#23335907)
Is encapsulation different in either case? Nobody should be operating directly on the state, any more than they should be reflecting on private fields in a class.
Re:The use of `class` for things that should be simple free ... by Barrin92 on Thursday May 28, 2020 @04:32AM (#23334891)
If you're at the point where you'd rather pass a state argument around rather than use an object you've thrown out OO categorically and there's no point to even discuss anything. The article in question talks about when it makes sense to use functions within the OO paradigm instead of classes.

Generally using classes when modelling persistent state is not an anti-pattern, because that's what classes are for.

Re:The use of `class` for things that should be simple free ... by crooked-v on Thursday May 28, 2020 @12:44PM (#23339421)
Nothing made this as clear for me as using the Nim language, where functions defined as

   proc doThing(x: MyObject; value: string)
can be called both with

   doThing(x, y)
and with

   x.doThing(y)
where x by itself is 'just' a data object, but is treated transparently by the language as having associated functions, setters, getters, etc as if it were a class (even though they can all also be directly called separately).

It's an approach that I find really elegant and that I wish more languages used in some way.

Re:The use of `class` for things that should be simple free ... by comfydragon on Thursday May 28, 2020 @07:12PM (#23344177)
That's a thing you can also do in Python:

    class MyObject:
        def doThing(self, value: str) -> None:
            # whatever
            pass

    obj = MyObject()
    obj.doThing("value!")
    MyObject.doThing(obj, "a different value!")
The only difference is that doThing is namespaced to the MyObject class.
Re:The use of `class` for things that should be simple free ... by mehrdadn on Thursday May 28, 2020 @12:59PM (#23339623)
You certainly can do that. You can also refer to John Smith as "Mr. Smith", even when he's your dad. Whether it's more natural or more jarring or confusing is another question though...
Re:The use of `class` for things that should be simple free ... by endgame on Thursday May 28, 2020 @04:09AM (#23334770)
Can't you close over the state, so the library doesn't need to see and pass around the extra parameters?
Re:The use of `class` for things that should be simple free ... by gbrown on Thursday May 28, 2020 @08:37AM (#23336525)
Isn’t that just axiomatic? Of course anything you can do with a class you can do with a function + state. The prose is to make that pattern more natural for humans to program and use.
Re:The use of `class` for things that should be simple free ... by raducu on Thursday May 28, 2020 @10:04AM (#23337341)
But after a couple of arguments, fields inside an object become more appealing -- this is about taste.

But even if you have free functions, as they become more complex, you tend to group them together, so at that point you might just slap the "class" keyword somewhere at the beginning of the file and just call it a class.

Re:The use of `class` for things that should be simple free ... by ImprobableTruth on Thursday May 28, 2020 @11:07AM (#23338195)
>But after a couple of arguments, fields inside an object become more appealing -- this is about taste.

I don't understand this. The difference between passing a structure implicitly or explicitly will always be a single argument.

>But even if you have free functions, as they become more complex, you tend to group them together, so at that point you might just slap the "class" keyword somewhere at the beginning of the file and just call it a class.

Sure, but at that point you're not really using any class features. If you're just using classes as modules, why not use modules directly?

Re:The use of `class` for things that should be simple free ... by otabdeveloper4 on Thursday May 28, 2020 @01:52PM (#23340244)
> ...a function that takes in an extra ‘state’ argument.

That's exactly what a 'class' is.

Re:The use of `class` for things that should be simple free ... by edflsafoiewq on Thursday May 28, 2020 @04:09AM (#23334769)
You're talking about s.f(x) vs f(s,x)?
Re:The use of `class` for things that should be simple free ... by rocho on Thursday May 28, 2020 @03:49AM (#23334622)
Precisely. And that's the way it's done in functional languages.
Re:The use of `class` for things that should be simple free ... by millstone on Thursday May 28, 2020 @04:20AM (#23334837)
No, it's done inverted in functional languages!

In a FPL your graph will be an ADT. The advantage is clients can pick it apart, but there is no easy way to extend it. If you wanted to "use the same object for computing distances to multiple vertices", you're screwed: the ADT is laid bare, and there is no data hiding.

In an OO language, your graph will be an opaque object, and you can write things like CachingDijkstra or ParallelDijkstra and make these work transparently for your clients. The price is that you are bound to your APIs: a client cannot pick apart your data structure, because it's opaque.

Re:The use of `class` for things that should be simple free ... by bo1024 on Thursday May 28, 2020 @06:41AM (#23335761)
I think using existential types will give you data-hiding like this. (Disclaimer: I'm still learning about them, and making up this syntax.) Say my abstract data type is

    DijkstraLib =
    there exists GraphState with {
        construct: List(Edge) -> GraphState
        getDist: GraphState -> Vertex -> Vertex -> Num
    }
Now we can write two different implementations of this type that use a different data structure for graph. The data structure will be opaque to the client (even though the client obtains and passes around graph objects!). Like so:

    -- Library
    type CachingDijkstraLib : DijkstraLib
    with GraphState = (HashMap((Vertex, Vertex), Num), List(Edge))
    with {
        construct(a_list) = (HashMap.empty, a_list)
        ...
    }

    -- Client
    DL = CachingDijkstraLib : DijkstraLib
    some_obj = DL.construct(edge_list)
    DL.getDist(some_obj, u, v)
    DL2 = SomeOtherDijkstraLib : DijkstraLib
    some_other_obj = DL2.construct(edge_list)
    DL2.getDist(some_other_obj, u, v)
The types of some_obj and some_other_obj could be completely different, and neither would be accessible to the client. For example, the client couldn't assume some_obj is a pair and try to get its first element. It would also be an error to call e.g. DL2.getDist(some_obj, ...).
Re:The use of `class` for things that should be simple free ... by taejo on Thursday May 28, 2020 @06:16AM (#23335586)
The A in ADT can stand for both abstract and algebraic, so it's an unhelpful abbreviation in contexts where both algebraic and abstract datatypes are relevant.

Functional programming languages tend to have good support for algebraic types (which I think you mean) but they can often do data-hiding too! In Haskell, for example, you do this by not exporting the data constructors for your type, so they can only be used within the module that defines the type.

Re:The use of `class` for things that should be simple free ... by danielscrubs on Thursday May 28, 2020 @06:06AM (#23335527)
We do have data hiding in functional programming, even if we would not have modules, which we do, we do have type classes, and for example in OCaml you can hide constructors if that's your jam.

It's not like when I use a sorting function that the implementors couldn't swap it out for a caching one or a parallel one.

One of the amazing things I remember is changing an int to a float in a very well used "struct" that was touching thousands of functions but because the functions in Haskell usually so extremely general I didn't have to change a single other line (Number type is heavily used and doesn't incur an extra performance cost, which it very much does in Java).

In fact we can be even more precise or loose in what assumptions need to be made via dependent types in functional programming languages like Agda.

I encourage you to take a look at any popular Haskell-framework to see how it's done in practice.

Re:The use of `class` for things that should be simple free ... by layoutIfNeeded on Thursday May 28, 2020 @06:38AM (#23335738)
Cool idea! Actually, you could probably call this extra argument "this".
Re:The use of `class` for things that should be simple free ... by loopz on Thursday May 28, 2020 @08:06AM (#23336285)

  void do(withThis, that) {
    that(withThis)
  }
Why be implicit with anything, when you can provide nice headscratchers for the next clown! ;-)

Seriosuly though, most OO-languages brings not much to the table other than being "OO-centric" (methods+data vs procedures|functions). OO without encapsulation of data and implementation though, may even be worse abuse than no OO. So one can by convention even do OO without direct support for it in the language itself, by using any form of indirection that encapsulates data and implementation. REST typically fails this, because it often exposes direct access to internal resources (CRUD).

Re:The use of `class` for things that should be simple free ... by quietbritishjim on Thursday May 28, 2020 @08:57AM (#23336676)
If you do use a class for this, of course you can provide a wrapper function that constructs the object, calls the "run" method on it, and returns the result. This can be in addition to the processing class, or it can be the entirety of the public API while the processing class is defined privately in an implementation file.

I've done this before for Munkres, also called The Hungarian Algorithm, which assigns jobs to workers. Logically the interface is a simple function, but internally it's very useful to have a class with multiple private methods.

Re:The use of `class` for things that should be simple free ... by mehrdadn on Thursday May 28, 2020 @09:02AM (#23336725)
Yeah, I almost suggested a static method for the common case too. It's nice to have a convenient interface for the simpler use cases.
Re:The use of `class` for things that should be simple free ... by throwaway894345 on Thursday May 28, 2020 @02:29PM (#23340652)
Isn’t this all just different approaches to currying? It’s often convenient to have some function that you can call without passing the same subset of parameters to each invocation. Whether to curry depends on how much repetition is involved and how “expensive” it is for the programmer to curry. In the case of “curry by creating a whole named class”, the expense is relatively large, while a functional currying approach is much cheaper.
Re:The use of `class` for things that should be simple free ... by quietbritishjim on Thursday May 28, 2020 @05:49PM (#23343173)
I'm not that familiar with functional programming but I think the answer is no. In the situation I'm describing, most of the arguments to the private methods are completely different except for the implicit this/self argument that contains the progress of the algorithm. Currying is about turning a function of multiple arguments into a function of one argument which itself is a function (which in turn takes a function as an argument, and so on). I don't see the connection. Maybe you could clarify?
Re:The use of `class` for things that should be simple free ... by throwaway894345 on Thursday May 28, 2020 @08:55PM (#23345087)
If you have a function `foo(a, b, c)` and you find yourself passing the same a and b all the time, you can curry it into a function that only takes c: `f = curry(foo, a, b)` such that you can just call `f(c)`. The OO alternative would be to create a class:

    class Foo:
        def __init__(self, a, b):
            self.a = a
            self.b = b

        def f(c):
            return foo(self.a, self.b, c)
And then you create an instance `obj = Foo(a, b)` and when you need to call `foo`, you call it via `obj.f(c)`. This is a long winded way of saying an object is a poor man's closure.
Re:The use of `class` for things that should be simple free ... by quietbritishjim on Friday May 29, 2020 @05:12AM (#23347892)
Ah I see, I believe you've mixed up currying with partial function application, that's what confused me (but, again, I'm not an expert on functional languages so it could be me that's mixed up). I believe that currying doesn't take any arguments except the function itself:

    # Signature of f is (a, b, c) -> r
    g = curry(f)
    # Signature of g is a -> (b -> (c -> r))
    #    i.e. g is a -> blah, 
    #    where blah itself is a function taking b, etc.
Admittedly you can get partial function application out of currying (but only with parameters at the start of the parameter list):

    g = curry(f)
    h = g(a)(b)
    # Signature of h is c -> r
But, although they're related, they're different procedures overall: sometimes you'll really want the curried function without immediately applying some arguments to it.

Anyway, replacing "currying" with "partial function application" in your earlier comment: I suppose you're right to some extent, but the "this" parameter usually isn't that hidden and in Python you even pass the "self" parameter explicitly. I suppose the real major thing is you've put a bunch of parameters into a single class/tuple/struct rather than spelling them out individually; if you had a weird language that didn't support structs etc. then some partial function application would certainly be a very useful alternative to writing the same argument list out many times. But once you've got the struct, making your utility functions be methods is just minor syntactic sugar on top of that.

Re:The use of `class` for things that should be simple free ... by throwaway894345 on Friday May 29, 2020 @09:53AM (#23349973)
Yeah, you’re probably right. I don’t understand all the tedious, annoying functional jargon; I just know there is a function in Racket called “curry” which does what I described above. Sorry for my error.

> I suppose the real major thing is you've put a bunch of parameters into a single class/tuple/struct rather than spelling them out individually

Yes, this is the mechanic, ultimately. Partial application vs structs/objects/tuples are just two different solutions for the same problem. Arguably they may even reduce down to the same underlying solution (to the extent that closures are objects behind the scenes).

Re:The use of `class` for things that should be simple free ... by chrischattin on Thursday May 28, 2020 @01:55PM (#23340279)
I get how this works and the reason for it. It just doesn't feel DRY to me. Like we're adapting to satisfy a pattern vs the pattern serving us and our dev goals. Aesthetically unpleasing, imo.
Re:The use of `class` for things that should be simple free ... by encoderer on Thursday May 28, 2020 @02:13PM (#23340460)
We suffer so many bad abstractions at the church of DRY.
Re:The use of `class` for things that should be simple free ... by mehrdadn on Thursday May 28, 2020 @04:53PM (#23342448)
There's nothing repeating here... you define a procedure to achieve a higher-level task, which is a combination of other tasks. Kind of like File.ReadAllBytes() vs. FileStream. Later you use it when you need to perform that high-level task.
Re:The use of `class` for things that should be simple free ... by anonymoushn on Thursday May 28, 2020 @06:13AM (#23335563)
(a), (c), and (d) seems to be about exposing the algorithm's state and a function that performs a single step of the algorithm, rather than about having a class.

(b) seems like quite a bit of trouble, since the clone function must either copy the underlying graph by default or provide a mechanism for swapping out the underlying graph that fixes up the internal map of (node->distance) and the internal priority queue to refer to things in the new graph.

Re:The use of `class` for things that should be simple free ... by Laremere on Thursday May 28, 2020 @03:01AM (#23334328)
I believe you describing at least one of two cases: 1. There are multiple methods on the object (not counting constructor) 2. There are arguments passed to the methods.

Either of these cases are different from the provided example: The example will only ever compute a single value per object, always returning that value from a single method with no arguments (other than self).

Re:The use of `class` for things that should be simple free ... by twic on Thursday May 28, 2020 @03:48AM (#23334615)
Right. I think the article is talking about one very specific case, which is apparently common amongst novice C++ programmers, where there is a single computation, whose only inputs come from the constructor, and which gets done in a method.

There are plenty of cases where it makes sense to wrap a function in an object, but the point of the article is that this isn't one of them!

Re:The use of `class` for things that should be simple free ... by mehrdadn on Thursday May 28, 2020 @03:04AM (#23334347)
Not necessarily. What I said can apply to even a class with with 1 method that takes no arguments... though you might often recognize it as a more sophisticated kind of iterator:

  class BFS(object):
    def __init__(self, origin): self.origin = origin; ...
    def next(self): ...
Re:The use of `class` for things that should be simple free ... by wwright on Friday May 29, 2020 @08:00AM (#23348925)
IMO it’s even simpler to use a monad-type extension to functions to suspend state. (This can be coroutines/generators, explicit Haskell monads, some macros encapsulating longjmp or whatever.)

    queue <- { root }
    while queue is not empty
      node <- dequeue one node

      # One of the following:
      # for a simple function approach…
      if predicate(node)
        return node
      # or for a monadic approach, can be overloaded generically…
      yield! node

      for child of node
        enqueue child
The monad-style extensions fits with the other pieces of the language much more naturally IMO. You could easily use a predicate monad to regain the functionality of the naive implementation, or a more complex monad if you want a complex BFS traversal, but the function looks almost identical either way.

Python and Ruby and Lua and JavaScript even do this! C++20 will probably make this somewhat more common too.

(The word “monad” may set off sirens here, but it really just refers to a feature similar to but somewhat more generic than “yield” in a coroutine/generator.)

Re:The use of `class` for things that should be simple free ... by jvanderbot on Thursday May 28, 2020 @01:32PM (#23340037)
You're describing a classic use of iterators, which is itself a classic use of Objects-as-contracts.
Re:The use of `class` for things that should be simple free ... by crimsonalucard1 on Thursday May 28, 2020 @11:50AM (#23338700)
You still hit the same issue and you can still solve it the same way by converting that class with saved state into just a function.

Below are two short examples of two different ways to do this:

   type Node = Null | {value: int, left: Node, right: Node} 
   //a Node is NULL or a value that is an int with left and right nodes

   //procedural with mutation, saved state is placed in parameter: found
   def find_n_and_print_all_DFS (node: Node, search_value: int, &found: Node) -> Void:
      if node == Null:
         return
      else:
         print(node.value)
         *found = node.value == search_value ? node : Null
         find_n_and_print_all_DFS(node.left)
         find_n_and_print_all_DFS(node.right)


   //functional, no mutation, saved state is returned
   def find_n_and_print_all_DFS (node: Node, search_value: int, found: Node = Null) -> Node:
      if node == Null:
         return found
      else:
         print(node.value)
         found = node.value == search_value ? node : Null
         left = find_n_and_print_all_DFS(node.left, found)
         right = find_n_and_print_all_DFS(node.right, found)
         return left != Null ? left : right


I would argue that if I used classes the code would be way harder to read and much more verbose.

You can essentially use tail recursion on that DFS and pass in some accumulator as a parameter into your DFS or whatever. That accumulator can be some pointer representing some saved state or anything you want. There is still no need to group everything together into an Object.

It's a bit trickier but in the second example you can see that you don't even need to mutate anything at all. What you described can be achieved without redundant OOP classes and without mutating state at all! Additionally setting found to have a default value of Null negates the need for the extra accumulator parameter during function calls as you can just call it like this:

     saved_node = find_n_and_print_all_DFS(x, 5)
I would still say OOP is an anti pattern because it overall promotes adding these mutating parameters in your code even when you don't need save states or anything of that nature. In OOP, the existence of getters and setters and methods for accessing variables outside of the definition of the method itself heavily promotes this type of coding style regardless of whether or not it is needed.

The procedural style forces this additional "saved" feature to be evident as an extra parameter. If you never use that parameter it becomes obvious that the parameter is redundant while in OOP mutating external state is an intrinsic part of the style and like the OPs example you have to go through several logical leaps to see how redundant it is.