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.
The use of `class` for things that should be simple free functions
211–220 of 406 posts
Re: The use of `class` for things that should be simple free functions
#212I’ve always done it this way:
double calculation(double arg) {
thread_local bool prev_arg_valid = false;
thread_local double prev_arg;
thread_local double prev_result;
double result;
if(prev_arg_valid && prev_arg == arg)
result = prev_result;
else {
//do the calculation
result = ...;
prev_arg = arg;
prev_result = result;
prev_arg_valid = true;
}
return result;
}Doing it this way is something you would only ever do if you knew beforehand the user would be asking for the same value over and over, but it’s clean and invisible to the calling code and doesn’t break your assumptions about what the function is going to return.
The memoization pattern is valid too of course, I just find it interesting I’ve always done the same thing when advantageous but in a different way.
Re: The use of `class` for things that should be simple free functions
#213Earlier 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.
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…
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 functions
#214Earlier 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.
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 functions
#215Earlier quoted context omitted.
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 a…
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 functions
#216Also 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.
def x():
expensive precompute
def y():
cheap stuff
return y
It's a matter of taste I guess.Re: The use of `class` for things that should be simple free functions
#217Earlier quoted context omitted.
that only works if you are in a context where you can deduce the type from ctor arguments, which is definitely not all cases (for instance, storing as a member and initializing in a ctor, etc...)
You can then specify the function pointer type, although mildly inconvenient. If you want to use lambdas though, then yes, you are out of luck as their type is unnameable.
In the context of C++, struct / class types are more generic that function pointers and there's no real shortcut around this - that's how the language is specified.
Re: The use of `class` for things that should be simple free functions
#218Earlier 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.
Re: The use of `class` for things that should be simple free functions
#219Earlier quoted context omitted.
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 imp…
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.
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 functions
#220Earlier quoted context omitted.
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.
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.