Live data from Hacker News

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

quuxplusone.github.io

201–210 of 406 posts

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

#202

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

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.

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 functions

#203
post #87

Earlier quoted context omitted.

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

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…

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

#204

Earlier quoted context omitted.

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

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.

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 functions

#205

Earlier quoted context omitted.

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.

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.

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 functions

#206
post #87

Earlier quoted context omitted.

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…

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

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 functions

#207

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

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 functions

#208
A real world example would be better. School projects are always filled with arbitrary requirements since you are writing for an audience of one. Maybe the teacher required them implementation to be a class and that you had to memoize the count. In that case the replacement is not the right implementation.

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

#209

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

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…

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 functions

#210
post #3

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

At the same time, if your function has an expensive initialization step that only needs to be called once (and doesn't change between calls), then the pattern of using `__init__()` + `__call__()` can be very nice.
Post reply on HN