English major here. I'm currently learning how to code as part of a bootcamp called (surprise surprise) "Coding is the New Literacy".
One of the things this program hammers in early is fundamental programming principles like OOP. A lot of MOOCs skirt around these topics, forcing you to 'build' non-functional apps first. I've taken those courses and learned nothing of real value.
This program, where I've been forced to learn algorithms, OOP, etc. has been of much higher value. It's been harder, but I feel like I'm actually learning the fundamental principles of programming.
I'll echo your sentiments: to learn how to program is to learn how to model systems.
I am trying to read between the lines of your comment and I _think_ you get this but I'm going to spell it out anyway:
"...fundamental programming principles like OOP."
The key word here is "like". OOP is actually falling out of favor as a successful way to express models. Make sure you investigate alternatives to OOP (functional, procedural etc). As a graduate of OOP myself, it's interesting and exciting to approach different paradigms. Experience tells me that the best practices obsess over what things "do" rather than what things "are" (which is a fluffy concept at best).
Anyway, tit for tat, YMMV. Glad you're doing something though.
How do you figure OOP is falling out of favor? I've seen a few arguments on HN (the old OOP vs FP discussion) but do you actually expect the trend to continue to the point that no one really uses OOP anymore? Highly doubtful. And which specific part of the industry is OOP slipping into obscurity?
It's not so much that OOP is falling out of favour, but that functional programming in particular is being rediscovered, probably because we have to multithread now, and if bugs are hard to keep out of single-threaded code, they're nigh on impossible to keep out of multi-threaded code.
In fairness, a lot of us never truly embraced OOP anyway. I've always avoided objects unless I'm managing state. Even in OOP languages, much of my code essentially repurposes objects as modules for storing functions. The fact that they are implemented as methods is incidental. This is not an uncommon pattern.
I'm stronger with OOP than I am with functional programming because I've been doing OOP for longer. I started out with procedural programming when I was a kid (BASIC and QBASIC), and have since moved on to PHP, Javascript, Python and a bunch of other stuff.
Almost everything I've worked on in the last 8 years has involved OOP in either PHP, Python or Perl. Perhaps I stumbled into a niche and have yet to find my way out, but OOP has been a common theme in my career.
No, you stumbled into the mainstream. The wholesale migration to OOP was complete by the end of the 90s.
But you've probably been doing functional programming within OO languages and not realising it. For example, most of the PHP standard lib is functional. In fact, PHP is really a multi-paradigm language. Python is much closer to a pure OO language.
No, I do realize that PHP in functional. I suppose I misstated my history a bit - I went from procedural to scripting languages, to functional to mostly OOP in languages that support both functional and OOP.
I would say that Python isn't closer to a pure OO language than PHP, rather it allows for more pure OO than PHP. I only say this because you can go pure functional in Python as well.
It was popular in the 90s and early 00s to apply OOP techniques to everything, whether or not it made any sense. Today we use value types and higher-order functions all over the place, we customize objects with composition instead of inheritance, and we use module boundaries for encapsulation.
It doesn't help that it's easy to overdo your taxonomy, or try to model objects after the "real world" (rather than your domain model). Examples in some textbooks are pretty bad... if "dog" inherits from "animal" then you should throw the book out.
I would rather throw the book out if they had "dog" inheriting from "vehicle." Really, metaphors and analogies are nice, one of the most powerful parts of our capacity for human language. Just because math lacks those concepts, and so the same isn't possible in a functional mindset, doesn't mean it is bad.
Some FP textbooks are pretty bad...if fibanocci is implemented with just recursion, then you should throw the book out. </s>
My problem with "dog" and "animal" is not that I hate metaphors, but because the example tends to teach students that "X is a Y" is justification for "class X inherits from class Y". It's also usually found in books that focus more on the hammer than on the nails, if you know what I mean.
Recursive fib is usually taught to show how a naive translation of a recursive formula into code can cause poor performance. I can't think of a better example.
Reclusive FP is usssually the first example of the FP textbook, and is used to teach how elegant FP is from the beginnin jn spite of the fact that you should never write that (and who needs to write fib anyways). Inheritance is subtyping at the basic level: we all know a dog is an animal, and that all animals share a common ancestor. It is a crude instrument, especially in Java, and often can't be used, but not because the concept of extension is flawed in some ways. If you had traits/mixins, extension can be used much more widely.
I'm just as annoyed at the ideological "composition, not inheritance" crowd. The truth is, one has to learn a bunch of generalizations and then practice a lot to get it; good design is just hard to teach in a book.
FWIW, in my corner of the world (Scala, big data, web services) functional is very much the way things are going. It's a much better fit to the problem domain since all these systems very much look like pipelines. E.g. a web service is a function from request to respone. Big data applications are just applying some function over (possibly streaming) data.
It's happening on the front-end as well, with things like React.
Might be worth remembering that OOP was born out of a need to model the real world (SIMUlation LAnguage). I don't think it's a surprise that functions are a good way to work with mathematical models (that is, after all, how we do math).
For the front end, it's my understanding that event-passing systems are still used quite heavily -- which can also be considered OOP (message passing).
Modelling a car as a sub-class of vehicle etc -- makes most sense when you're modelling real-world objects.
You may be interested in the Actor Model [1] computation style. When used for programming, it looks like a programming paradigm where functional and object-oriented styles are neatly supported and blended without any impedance mismatches. Most code is written in a functional style, but there are abstractions that encapsulate state changes and make it work together with the mostly declarative functions.
There are at least a couple of Coursera lectures teaching this style (one about programming paradigms, the other about reactive programming), it's worth giving it a look.
The actor model isn't a computation style itself so much as a concurrency discipline loosely resembling the style of message-passing OO (a la Smalltalk).
It appears that some people have become so zealously opposed to object orientation that they have been unable to realize that not everything is Java.
> OOP is actually falling out of favor as a successful way to express models. Make sure you investigate alternatives to OOP (functional, procedural etc). As a graduate of OOP myself, it's interesting and exciting to approach different paradigms. Experience tells me that the best practices obsess over what things "do" rather than what things "are" (which is a fluffy concept at best).
This is like saying:
"Noun-based writing is falling out of favor as a successful way to express stories. Experience tells me that the best practices obsess over what things "do" rather than what things "are" (which is a fluffy concept at best)."
If a writer didn't use verbs and nouns when appropriate, nobody would read their writing. You would consider such a writer to be almost illiterate.
Of course it's useful for a writer to experiment with focusing on verbs or nouns, and there are situations where one may be so much more useful that the writer should eschew the other entirely. But a dogmatic approach that tries to eliminate all of one or the other universally is bound to lead to bad writing.
And the same goes for coding. Focusing dogmatically on one methodology is only going to limit what you can do.
> One of the things this program hammers in early is fundamental programming principles like OOP
OOP is not a fundamental programming principle. Its a recently popular programming paradigm. The idea that OOP is a fundamental programming principle is a harmful concept to internalize (though lots of programmers trained in the last ~20-25 years have internalized it.)
It's not the only way, and it's not always the best way. But I think you do a disservice to the English major you are replying to by suggesting he or she is learning something "harmful" to their future development.
I'm not saying your point is invalid or incorrect. I just think someone new to programming will be best served by learning how to write useful programs in one paradigm, before exploring multiple paradigms, or worrying about whether they are using the "right" one.
I would say the same thing to someone being taught the functional paradigm as a beginner. It will make more sense to compare with other paradigms in the future, once you have some mastery of one paradigm.
I didn't say (and don't believe) that learning OOP is harmful, I said internalizing the idea that OOP is a fundamental principle of programming is harmful.
Principles would be stuff in the form of "You should do things this way to end up with a better product, regardless of paradigm". Of the top of my head would be things like:
- Modularity/Separation of concerns: The different functions a program needs to accomplish should be uncoupled as much as logically possible, to the point where you could easily swap out one with another way of accomplishing the same objective without affecting anything else.
- Don't repeat yourself: Any time you're writing nearly the same thing over and over, that whole pattern should be abstracted away.
- "I've only proven it correct, not run it.": You should be able to test the software in an environment that shows you what it would do, without affecting the thing you really want to operate on.
- Write in a way that other humans can easily understand what you're doing. (e.g. name variables after what they're being used for, write comments help the code make sense and convey any tradeoffs)
Functions and types are fundamental. OOP not so much. Computation is fundamental, state not so much.
Higher-order functions are not quite fundamental (depending on your point of view) but pretty close.
One of the things this program hammers in early is fundamental programming principles like OOP. A lot of MOOCs skirt around these topics, forcing you to 'build' non-functional apps first. I've taken those courses and learned nothing of real value.
This program, where I've been forced to learn algorithms, OOP, etc. has been of much higher value. It's been harder, but I feel like I'm actually learning the fundamental principles of programming.
I'll echo your sentiments: to learn how to program is to learn how to model systems.