Live data from Hacker News

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

quuxplusone.github.io

351–360 of 406 posts

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

#351

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.

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…

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 functions

#352

In typescript I will for example make a class called 'Tools' with static 'free form' functions and no constructor. I do it just because it's easy to organize, import and call the functions. Is this bad?

Not saying this is "bad", but why not use a module for that?

Not sure. Maybe time to convert some classes to modules.

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

#354
post #163
post #112

Earlier quoted context omitted.

(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 That depends. Inheritance makes it easy to break encapsulation (which is bad -- agreed). It can be hard to model "Is-A"-Relationships properly, but I wouldn't call it inherently bad. A circle isn't an ellipsis; but a chair is furniture. The quality of code stems from your quality of thought. > this means tight coupling between them, rather often unwanted. That depends on your design. Coupling is…

Inheritance reminds me of https://www.pcgamer.com/heres-whats-happening-inside-fallout...

Your OpenConnection idea might make sense in some abstract way, but one thing I know about connections is that they have a habit of closing. They will close without any notice to your programming runtime, because the operating system will do it. What happens to your OpenConnection object then? Well it becomes invalidated, and now you have a nonsensical object hanging around. So you read from it, get an error, and... now what? Replace it with a ClosedConnection?

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

#355

A lot of time where I just write simple functions, I end up having to wrap them into objects because it is much more convenient when I want to do static polymorphism - sure, that function I'm writing now doesn't need state but then two days after I have to refactor because the next strategy I use does indeed require state. e.g. : template struct MyAlgorithm { F1 f1; F2 f2; void operator()(...) { ... f1(whatever); ...…

It's a trade off - if you want dispatch efficiency then use functions, if you want flexibility use std::function and you can store functions, functors or lambdas.

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

#356

Earlier quoted context omitted.

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

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…

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 functions

#357

Earlier quoted context omitted.

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

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

#358
post #79

Is there any real harm though? Free functions pollute the global namespace, which is something I tend to avoid (at least in Ruby where everything shares the same namespace).

Just put the function in a namespace?

In Ruby that looks a lot like what the article says is an anti-pattern.

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

#359
post #326
post #174

Earlier quoted context omitted.

> it's harder to make a function retain state later. I do not agree with this kind of argument. If you need to transform the function into an object later, you can just do it later. Even in a huge codebase it does not take much time to do it. The `what if [...] someday` argument only leads to unnecessarily complex and expensive code, and most of the time you will never actually need it.

It's not so much about "I need that later", but to start thinking about a program differently to begin with. If you think about the things that "are" rather than what should happen in what order, you get the chance to rearrange everything and do some optimizations that an eager processing might prevent you to do. Most of the OOP power comes from uniformity, which many systems break unfortunatelly. When you work with…

It seems to me that this is mostly a design problem. Why would you need to check this data everywhere?

Checking the validity of the data is only necessary once. In a web context, this is the responsibility of the controller. Only once the data is sanitized should the controller inject it into 'anything else'. Sanitizing data is not the responsibility of a model/service/repository/view/anything else, and trying to do so indeed leads to a lot of bugs and headaches.

Having this kind of object that checks your data and may throw exceptions anywhere on the code only augments the failure surface of all your codebase by adding unexpected exceptions.

Comprehensibility is in no way related to using objects. Wether you choose an integer, a class or a subtype of integer does not make anything more readable, it all depends on the quality of the naming. A var named `year` or `startYear` will always make the code more readable than a var named `start` or `begin`, whether it contains an object or an integer is irrelevant.

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

#360

Earlier quoted context omitted.

I felt as though I should know the moral of the story, yet I did not. https://stackoverflow.com/a/11421598 Moral of the story is that closures and objects are ideas that are expressible in terms of each other, and none is more fundamental than the other. That's all there is to the statement under consideration.

It's code and state. Nothing more. Nothing less.

My first computer book was: “Data Structures + Algorithms = Programs”. Thinking in this way has simplified my code tremendously. I think OO is taught because it’s more tactile. Literally it takes more keystrokes, and so much is pattern repetition that it facilitates learning and feels like progress. Functional is like learning Latin by studying Ovid one word at a time. When books (or mips) were expensive, this was how it was done. Even OO is old-school now though; today’s introduction to programming is mostly configuring CSS and webpack.
Post reply on HN