Casey Muratori on getting rid of OOP mindset [video]
youtube.com
youtube.com
If the language in question does provide OOP features, these features (well implemented or not) are probably not going to be taught in the normal path of education for the language. Thus, you probably won't have to make an effort to avoid them.
Again, this suggestion is for the new to programming segment of people; so also assuming these are undergraduate or younger level, I wouldn't suggest something like Haskell. While it is probably an excellent language to learn as part of one's path to being a good developer, it might be a bit steep for someone new to programming.
Instead, I would choose F#, Clojure, or Elixir in that order. I would not choose Scala, because there's more of a chance that some early educational material would be from the OOP perspective.
FP shops have tried since the early 60's to stay viable and expand, but usually fail outside of niche domains. I'm just the messenger. FP has had more than plenty of shots throughout history to prove its mettle in the real world.
I personally have found FP hard to debug. The "naked state" of imperative programming is actually helpful when debugging, because the context is laid out on a nice little e-desk to examine. With FP you mostly have to open and inspect one drawer at a time.
One FP proponent replied, "well, then make fewer bugs." No comment, other than reminding that one can't control other people's creation of bugs even if they can control their own.
I can very honestly say pure functions are the easiest thing to debug and test: Inputs, outputs. Trivial for unit testing.
I can't speak for MLs/Haskell, but debugging pure functions in any language tend to just be glancing at the stack trace, seeing the values on the stack going in, and then seeing where the unexpected wrong output came out, and being fairly confident knowing the issue is going to be in that function.
> The "naked state" of imperative programming
Are we including OO in this definition? The fundamental design pattern of OO is to encapsulate state. It's anything but naked, always being wrapped in object instances, only accessible via getters/setters, scattered into a million pieces across many instances of the system.
Conversely, Clojure has the most naked state ever. There's usually little to no state, and the current state is right there on the stack. Most simple Clojure programs with state have a singular atom aptly named "state" which is passed around, easy to inspect and modify as it's a simple data structure.
I think, ultimately, there's a common conflation of "Functional Programming" meaning "Declarative Type-Driven Functional Programming", when the reality is there are alternatives to ML/Haskell, aside from applying Functional patterns in "non-functional" languages.
As an analogy, depending on which spoken language a person learned first (as a child, _automatically), learning some new languages may be particularly difficult or quite natural.
If we had all learned functional programming concepts first, our minds would be trained to think that way. We all learned functional (declarative) math, and we don't even think about it as such. It's just math.
This video gives some plausible explanations as to why imperative programming is more common than functional: https://youtu.be/QyJZzq0v7Z4
Observations of various organizations that tried it seem to confirm this. They have problems after the original team leaves.