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