Live data from Hacker News

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

quuxplusone.github.io

291–300 of 406 posts

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

#291

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…

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 functions

#292

Earlier quoted context omitted.

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

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

You're saying what? Doing objects that act just like closures? :)

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

#293
post #112
post #95

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

(1) Interfaces / typeclasses / traits are good; inheritance is bad. An object is a family of partially applied functions with some shared state; this means tight coupling between them, rather often unwanted. (2) Not having mutable state is the point . The more state you have, and the more code paths can mutate the state, the harder it is to reason about the program correctly. Examples of various degrees of hilarity /…

> inheritance is bad

Inheritance is a common-sense solution to the problem of creating something similar to an existing object, but different in some key aspects. It's programming by difference. Nothing bad about it until you start using it for type information.

>An object is a family of partially applied functions with some shared state

This is not true because of dynamic dispatch and because in non-sucky languages objects can interpret messages.

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

#294

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.

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

#295

Earlier quoted context omitted.

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

You're saying what? Doing objects that act just like closures? :)

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 functions

#296

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…

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 functions

#297
I know that there's arguments for and against classes and functions. In recent years, I've come to love functions. But they are both tools that have cases of appropriateness.

However, I think a lot of people are looking at classes the wrong way.

In this thread, I'm hearing that classes should encapsulate functionality. While this is an aspect of classes, I don't think it's the main use case of a class.

A class should represent a type of state. That is, if you create an instance of a state, it should only support the attributes and default properties that are defined for it. This is mainly for shorthand(there's usually a syntax to build instances of classes) and for clear documentation. At a lower level, the availability of a class construct makes it possible for AST parsing to do interesting things to your OO code, although I don't know how common that is outside of JavaScript. If JavaScript didn't support class syntax, it'd probably be more difficult to implement things like decorators, both in terms of the Babel plugins that support it as well as future native syntax support. But I digress.

The way I see it, a class should be responsible for holding a mostly fixed set of attributes, setting defaults for those attributes, and have properties that compute off other properties.

What doesn't belong in a class are methods that do complex things with other objects and class instances. If your method does something complicated that affects outside state, it's time to extract it to a function that takes a context argument. This makes it easy to test your function without necessarily having to meet all the requirements of the classes you'd be using with it, and it makes the code more flexible because you can use it for other contexts besides a single class. (I know that you can use inheritance and composition to kind of do the same thing, but I think this sucks because inheritance introduces problems and composition just adds more code than just importing a function where you actually need to use it.)

More concisely, a class shouldn't be looked at as a module, or a set of related functions that do complex things, especially when not all of those functions rely on a state. That's the job of an actual module construct in the language. Classes have a specific job, which is to build an instance of a type. If your class has a lot of functionality that's not totally dependent on the class instance itself, it doesn't belong there in my opinion. Just because a class can be used like a module doesn't mean that it should.

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

#298
post #143

Earlier quoted context omitted.

I am not sure I understand your differentiation of explicit and implicit state. I believe you refer to Objects that change their internal values over time; in that calling the same function twice yields different results. Of course, such objects can be a pain to use. Objects are all about making state explicit. Constructors connect different primitive values to a higher order concept, goal or task and checks invarian…

I think your Wallet.pay(amount) example argues for a different conclusion than you arrive at. I have a Wallet with $500 in it. I call Wallet.pay(100). In your approach, it returns a new Wallet with $400 in it. But I also still have the old, unmutated Wallet with $500 in it, which could be referred to by mistake (or by malice). That's probably not the best argument for immutable objects...

That's actually an argument in favor of linear or affine types. In your example, you'd still get a new Wallet from that function, but the compiler would keep you from accidentally using the old one afterwards. That way, you can't make that mistake, but still get the benefits of immutability.

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

#299
post #257
post #118

Earlier quoted context omitted.

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

True, I'm working with Swift which doesn't have that concept. But you can't have collisions between similarly named functions that are in the main or a different namespace? For example when somebody defines it's own version of 'print'?

You can have name collisions of functions with the same name, same namespace and same signature. But you can have nested namespaces, so namespaces are still the answer in c++.

In languages where those are not available or where you are forced to use classes anyways (e.g., java) I see no problem with classes-as-a-namespace, but especially in java there is no point in discussing "classes that should be free functions", too, as those don't exist.

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

#300
post #95

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

You only lose deferred execution in this case because it didn't go far enough away from OOP and toward FP. For example, since Haskell is a pure functional language, it can be lazy by default, meaning the function-only version transliterated there will have deferred execution.
Post reply on HN