no. 11| 06.03.2014 |
Functional OOP.
Answering this question took me a while. There was some sorting out to do. I’m starting to get my head wrapped around this, but be warned, gentle reader — grain of salt.
Functional, Procedural, Imperative, Declarative, OOP. What?
There’s a Venn diagram here. Let’s start with two big separate circles — umbrella categories that describe broad programming paradigms. Imperative vs. Declarative.
Imperative languages are like a recipe or a to-do list — a set of instructions that describe how to get a result. BASIC is one example of a language that fits in this category.
In contrast, declarative languages describe what you want as a result, and it’s the computer’s job to figure out the how. The HTML that defines a web page, or a spreadsheet with cells of formulas are examples of this. (So is SQL, apparently.) Declarative languages are generally described as “higher level” than imperative — there are more layers of abstraction between the programmer and the machine hardware.
Functional languages are a subset of the declarative category. The code is often structured like mathematical equations or functions. Many functional languages are “impure”, meaning they contain some imperative features, but Haskell is one oft-cited example of a “pure” functional language.
Any googling on imperative and declarative languages will quickly turn up references to “state” and “side-effects”. Wikipedia here we come: State. Side-Effects.
Imperative languages are all about side effects. Functional languages generally avoid them. I find the recipe / spreadsheet examples helpful here. As you move through the kitchen, you can see things changing over time, and state and order matter. (You can’t cook an omelette before you scramble the eggs.) A spreadsheet, once you specify all the “whats” — the cell values and functions — is Bam. Done. Changing one value changes all the values in linked cells at once. It’s really just one big single equation, despite being broken into smaller visible parts. How the computer is figuring out the answer to that big equation? Not your concern.
Now for the object-oriented part: Ruby.
Ruby is actually considered a multi-paradigm language. It’s generally imperative in form, and uses object-orientation as the model of organization for its imperativeness. But it also includes functional components — like map and reduce. You could write a set of instructions in Ruby that describe, step by step, how to loop through an array and do something to each element. Or you could just call map. Bam. Done.
It was interesting to see the (oh, of course there is) debate around internet town about the heavenliness or stanky-evil-ness of the different programming paradigms. Generally, it seems to me like most things: it depends on the context, the task at hand, and programmer skill. It’s less about the particular tool and more about how it’s being used.
I did appreciate explanations of how functional programming is beneficial in contexts where parallelization is important. (i.e. Multi-core processors, or that giant Cloud thing people won’t shut up about.) The lower level “how” can change under the functional code without much impact.
While Ruby isn’t considered a functional language per se, there are techniques to code in a functional style in Ruby. For some tasks this may improve the quality of code. It’s nice to find that tool in the toolkit.