It's about state and functions. He is saying rather then have an entity manage both state and functions, Just have a function take in state. The implementation details are besides the point. Why? Because you can arbitrarily wrap that socket up with ANY type of wrapper if you don't like "implementation details". Wrapping it up in a lambda is probably the worst thing to wrap it up in.
He is saying that the trade off of a slightly larger function signature that takes in an extra "wrapped socket" is WORTH higher modularity and composability and lower complexity.
Example:
writeStringToWrappedSocket(s: WrappedSocket, s: str)
writeStringToFile(f: File, s: String)
print(s: str)
generateLogString(s: str) -> str
generateFilteredString(s: str, match: str) -> str
capitalize(str) -> str
appendSuffix(s: str, suffix: str) -> str
generateCapitalizedFilteredString(s: str, match: str) = capitalize(generateFilitedString(s, match))
logCapitalizedFilteredStringToSocket(s: str, match: str) = writeStringToWrappedSocket(wrappedSocket, generateCapitalizedFilteredString(s, match))
logFilteredWithDateToFile(s: str, match: str, f: File) = writeStringToFile(appendSuffix(generateFilteredString(s, match), time.date), f)
Boom look at that! How many different types of logging functions can you produce simply by composing some primitives together? I have achieved greater compositional flexibility then OOP in MUCH fewer lines of code and significantly less complexity. With OOP you need an ENTIRE ARTICLE to explain strategies trying to get around a problem caused by over complicating things.There is a cost to just using normal primitive functions and avoiding classes. What's the cost? The function signature needs to take in a wrapper to a socket while the OOP version doesn't? No that's not much of cost. The actual cost is more subtle. The version I present here is propagating logical management of the lifetime of WrappedSocket to be handled by the parent context. It's not really a "cost" per say, it's just shifting the problem somewhere else. This is much less of a concern for most popular languages where garbage collection handles the lifetimes. Which is another way of saying if you're not using C++ the above method is the better way to go then OOP. And if you're using OOP, then the above is a library that can ONLY be used in the context of the class as some destructor has to call file.close().
Note I am not saying that OOP is bad. It works for many use cases. But it is also in general one of the LEAST modular and reusable patterns in programming. It is also over used and over popular. You use it when you have no choice. I am also NOT promoting functional programming.