9 ms·
Have you seen bad OOP code? It's an unreadable mess of ObjectManagerFactory classes where everyone mutates everything. Have you seen bad functional code? It's
by jehna1 7y ago
Have you seen bad OOP code? It's an unreadable mess of ObjectManagerFactory classes where everyone mutates everything.
Have you seen bad functional code? It's an unreadable mess of monads, flatmaps and partial composition where you're not really sure how many arguments a curried function is whitholding.
Have you seen bad procedural code? It's an unreadable mess of nested if-else statements where you're not really sure what state the world is in.
There are no silver bullets, only different solutions to different problems
- kjeetgill 7y agoThis post really needs to be the required reading before any PL paradigm discussion. If only dang could pin it to the top of every post with OOP in the title
- psetq 7y agoI agree. The only way to have this language paradigm discussion productively is if we're all looking at two well written implementations of the same project in each. Even then, I think the final conclusion (most likely "agree to disagree") will be that it's largely subjective, and heavily biased by familiarity. Ultimately though, it's really just a distraction to avoid the much more controversial discussion we need to be having vis-à-vis tabs vs. spaces.
- joelfolksy 7y agoI would much rather struggle to interpret a complex expression (monads, partial application) than struggle to simulate a sequence of mutations (that potentially spans the entire object graph).
- nafizh 7y agoIt's much easier to write bad OOP and procedural code, TBH.
- ivanhoe 7y agoyes, but it's also much easier to write a good OOP code... learning curve is way steeper for functional programming, OOP is easier to grasp as it's closer to how we usually think of the world, while FP is more math like...
- raverbashing 7y agoWe also have a lot more of "holier than thou", gatekeeping, guidance that's more subjective than objective but taken as gospel like "SOLID", "clean code", stuff like MVC where your circular system is made to fit a square hole etc in OOP.
- kerkeslager 7y agoOkay, but how we think of the world is a pretty poor way to program computers. If you write objects to act how we think of the world, then you mutate state within your objects, and when you add threading it becomes a mess. You can avoid this with immutability, but then you start doing stuff like replacing one Person with another with one property changed, and you're no longer treating Objects like they are in the real world. A lot of good OOP practices like this are built in and somewhat enforced in FP. For example, the single responsibility principle: which psuedocode implements single responsibility better? immutable class Schema: Schema(self, ...): ... bool check_document(self, Document document): ... Schema with_constraint(self, Constraint new_constraint): ... Schema without_constraint(self, Constraint old_constraint): ... ...or... ... -> Schema make_schema(...) ... Schema -> Document -> bool make_schema_checker(schema) ... (Schema, Constraint) -> Schema add_constraint(schema, constraint) ... (Schema, Constraint) -> Schema remove_constraint(schema, constraint) ... Sure, you could separate out `class ConstraintChecker` and `class SchemaBuilder`, but you might not think to do that at the time, it costs an extra file, what's the harm, right? And I really doubt many OO programmers would go to the lengths of separating `class SchemaBuilder` into `class ConstraintAdder` and `class ConstraintRemover`. In fact, that would be so verbose that I'd probably argue that it's not good code. Meanwhile, the same functions in a functional style are each already separated because that's the only option for to do it, and it doesn't come with the verbosity cost. Closures are inherently single-responsibility objects, so much so that you don't even need to specify which method on them you're calling, you just call the object itself and it does the only thing it could possibly do! I suppose it might be more intuitive to do this: (Schema, Document) -> true check_document_against_schema(schema, document) Which would force you to leak the concept of the Schema to places that don't need to touch it, but at least check_document_against_schema still has a single responsibility.
- tolmasky 7y agoI feel that it is in fact possible to learn from history, and what humans tend to be good at and bad at, and derive useful directions for the future. "Use the right tool for the job" and "no silver bullets" are certainly tautologically correct, but they seem to miss the point of these discussions: we have a choice in what paradigms we teach, what frameworks we write, and what tools we use. How do we choose the right tool? These platitudes often have the (unintended?) consequence of effectively serving as veiled gate-keeping: "silly novice, you thought learning X was sufficient? No no, you must learn all the possible paradigms, and at some point you will become aware of which one to precisely apply for any given problem. Me merely telling you the solution would be cheating!" Practically speaking, in my opinion, beginning teaching programming with an OOP approach can be detrimental to students. When I see students work in procedural (not even functional!) environments, they seem to piece together "the puzzle" of the programming task, whereas in OOP environments they often seem to devolve into strange taxonomical metaphysical questions "Is a Car a Vehicle? Or does it implement Drivable? Is a Window a Widget itself, or does it only own Widgets? If it's a Widget itself, then could a Window contain sub-windows?" So at least for the very constrained question of introductory languages and techniques, I think there is nothing wrong with specifically calling out certain approaches, vs. vaguely attesting to the truism that you can write bad code in any language. This feels similar to when people discover the concept of Turing Complete, and thus conclude all languages must thus be equivalent and any programming language discussion is thus moot. No. If that were the case, we should have never bothered going past assembly.
- yoz-y 7y agoWhat courses or universities actually start with OOP? In my uni we started with functional programming (Scheme) and then went to C, only then we learned Java, C++, Prolog and so on. In another uni when I supervised some exercise classes all students started with Python but using only imperative paradigm.
- tolmasky 7y agoIn high school AP Computer Science uses Java (20 years ago when I was in high school, they were just transitioning off of C++). You can see what the earliest programmers are being taught here: https://apcentral.collegeboard.org/pdf/ap-computer-science-a-course-a-glance.pdf?course=ap-computer-science-a https://apcentral.collegeboard.org/pdf/ap-computer-science-a... Edit: When I was in HS, the AP CS courses (now there is only on since the second one was discontinued) used the "Marin Biology Case Study" ( https://en.wikipedia.org/wiki/AP_Computer_Science_A#Marine_Biology_case_study_(2000-2007) https://en.wikipedia.org/wiki/AP_Computer_Science_A#Marine_B... ). It has apparently been replaced with the "GridWorld" similar case study. I think it highlights one of the issues of OOP: a fascination with modeling, or perhaps over-modeling, the real world. Throughout the course you are expected to develop deep knowledge of a myriad of Fish and Fish Tank-related classes, which while perhaps an accurate preview into what working in an environment like Java is like, is not something that in my opinion succeeds in either exciting most students nor teaching them the "fundamentals" of algorithms and such. I think it can very much feel like a very complex and convoluted exercise in meeting the abstract goals of "categorizing" the world. Ironically, the insistence on modeling the world makes it feel frivolous and disconnected from any practical use -- which is incredibly sad since IMO CS could be the most practical math/science course you take. In my experience when you show kids the cool things that they can get computers to do for them, it can be more inspiring -- such problems do not lend themselves well to formalized class hierarchy drawing though.
- boardwaalk 7y agoThe difference between them is probably that the OOP was a solution to all problems in its heyday. And a lot of us are probably saddled with the resulting legacy code to this day. That never quite happened to functional code and procedural code was the only solution to problems at the time.
- AnimalMuppet 7y agoIn my opinion, C++-style OOP was a solution to a particular problem: Here's a procedural program. It's got some data. That data is grouped together for convenience in, say, C-style structs. The problem is that any function in the entire program can modify the data in the structs. When the data goes bad (self-inconsistent, say), that gives you a lot of places to look. Someone wrote a function that doesn't maintain the data in a consistent state, and it could be anywhere. In a 10-million-line code base, that could be a long search. C++ classes changed that. Nobody gets to modify the data except member functions (presuming no inheritance). Maintaining the consistency of the data is easier, because there's a very limited number of functions to look at to make sure they preserve the invariants. With inheritance, you can still do that for the parts that you make private. Now, is that the ultimate answer to how to do software development? Perhaps not. It was a step better than the way things were before, though.
- kerkeslager 7y ago"You can write bad code in any language" is fairly proven. Can you write good code in any language, though? At least, good enough? It's quite hard to study objectively, but my subjective opinion is "no". Trivially, brainfuck certainly doesn't cut it, but even if you're only looking at serious languages geared toward general, production-quality programming, there's a lot of programming languages that are much easier to make mistakes in or abuse than others.
- akira2501 7y ago> Can you write good code in any language, though? Yes, absolutely. > At least, good enough? I think the better question is, can you write good code in a particular language and still make deadline?
- kerkeslager 7y agoI'd say you can't write good enough code in any language. The most high-profile, extensively tested C networking code still has security vulnerabilities, for example--the best C code isn't good enough. And broadly speaking, I'd say good code meets deadlines, but I guess that's a bit of semantics on my part.
- akira2501 7y ago> extensively tested C networking code still has security vulnerabilities Are you familiar with Daniel J Bernstein? > the best C code isn't good enough Are you sure _you've_ seen the _best_ code? Are you sure you understood the constraints of those writing that code when you evaluated it? > I'd say good code meets deadlines I'm trying to say there's an obvious compromise between the two, which explains the wide spectrum of code quality.
- mantap 7y agoIf you have to be DJB or Bellard to write good code in a programming language, that programming language probably has a problem. I used to write a lot of C back in the day, but I have to admit that C++ code is far more reliable and maintainable, which is a damning thing to say about any programming language.
- deleted 7y ago[deleted]
- ferzul 7y ago> Have you seen bad functional code? It's an unreadable mess of monads, flatmaps and partial composition where you're not really sure how many arguments a curried function is whitholding. not yet. can you point to any examples?
- env123 7y agoThe supreme question really is if you have a really great OOP code, a really great functional code and a really great procedural code, all achieving the same thing, which would be the best? ie. which would be best in front-end? in the back end? in services where you do loads of calculations and analysis? in services where you just need to retrieve data? It's probably best to be a full-stack developer, or find specialists who are really great at OOP and work on where it properly applies in the architecture system of a project, the same for functional or procedural We don't need to box ourselves (or a company) in OOP only (or functional or procedural if that's your main paradigm)
- flukus 7y ago> The supreme question really is if you have a really great OOP code, a really great functional code and a really great procedural code, all achieving the same thing, which would be the best? IME from a maintenance perspective (which is the only place you really find out what is and isn't good code) procedural is nearly always the answer, stupidly simple imperative logic is easy to follow and debug. In the UI you might want some more functional/event driven code but even then the bulk of it should be procedural. Most "great OOP" I've seen isn't all that OOP anyway, it's mostly procedural code with some OOP features used for name spacing.